一. 对象数组的递归排序
在项目开发中,老蝴蝶常常遇到这样的问题, 后端返回一个对象集合,如权限的表, 有 id,parentId,name 这样的自身关联的表, 在后端查询时,查询出来了一些数据,但是这些数据通常是错综复杂的,排序并不明显。 在Oracle 数据库中,可以通过 start with … connect by …语句来进行查询,但是在MySQL数据库中没有这样的用法。 所以,有时候,前端排序也是非常重要的。 这个方法,就是通过 子与父之间的联系,进行相应的排序, 需要id,parentId 这样的字段来进行指定,不需要级别来指定。 如果没有父的话,那么parentId=0,或者是空。
如一个权限表:
后端返回给前端的数据格式是,
太多,老蝴蝶这儿就简单截个屏两个了。
在表格中,用的是bootstrap-table 表格,响应的结果是:
function handleClientData(res){ var privilegeList=res.privilegeList?res.privilegeList:[]; return privilegeList; }
发现,这种展示方式很明显是不可以的。
可以通过一个方法,将响应的对象数组进行改变一下。
二. 通过递归,排序出新的集体。
方法中所用的 Map, 即new Map(), 并不是 JS的Map,而是老蝴蝶找的Map. 关于Map的内容,可以看老蝴蝶以前写的文章: JS的Map详细形式(十八)
深复制 DeepCopy() ,也可以参考老蝴蝶以前写的文章: JS的数组和对象深层拷贝(二十一)
/** * * @param data 要排序的对象数组 * @param idName id的编号名称 * @param pIdName 父级的编号名称 */ function listToTree(data,idName,pIdName){ //最后结果的集合 var resultData=[]; //存储 父下面的所有的子的集合。 key为父,value为子的集合。 var parentMap=new Map(); //存储第一级别,即刚开始的那个集合。 var firstLevelData=[]; //2。 为了避免造成对原来数据的干扰,进行一个深度的Copy. var resultDeepList=deepCopy(data); $.each(resultDeepList,function(idx,item){ var oldItem=item; if(!item[pIdName]){ //为空,或者值是0时,设置成-1. item[pIdName]=-1; } //放置父级 if(parentMap.containsKey(item[pIdName])){ parentMap.get(item[pIdName]).push(oldItem); }else{ var arr=new Array(); arr.push(oldItem); parentMap.put(item[pIdName],arr); } //取出第一级别的那些集合。 if(item[pIdName]==-1){ firstLevelData.push(oldItem); } }) diGuiTree(resultData,firstLevelData,parentMap,idName); return resultData; } function diGuiTree(resultData,data,parentMap,idName){ //放置过来的,是每一个的树。 if(data!=null&&data.length>0){ for(var i=0,length=data.length;i<length;i++){ var single=data[i]; resultData.push(single); //看是否有子级。 if(parentMap.get(single[idName])){ //有子级 var sonList=parentMap.get(single[idName]); if(sonList&&sonList.length>0){ diGuiTree(resultData,sonList,parentMap,idName); } } } } }
三. 响应时,调用新方法
写好了这个方法,在响应时进行调用。
function handleClientData(res){ var privilegeList=res.privilegeList?res.privilegeList:[]; //return privilegeList; //以前的调用形式 var resultData=listToTree(privilegeList,"id","parentid"); return resultData; }
刷新表格,展示:
四. 补充
展示有层次,是因为对 name那一列进行了设置样式。
<th data-field="name" data-align="center" data-cell-style="nameCellStyle">名称</th>
function nameCellStyle(value,row,index,field){ var level=row.level; return { css:{ "text-align":'left !important', "padding-left":(level*40)+"px" } } }
谢谢!!!