无限级分类和循环渲染
首先讲一下循环渲染。有时候我们会遇到存在父子关系的列表渲染,就像购物网站的类别选择,一层套一层,而父对子还有控制。如果挨着不停的去渲染代码会控制不住,所以循环渲染是必要的。下面是简单的代码实现。
<div id="app"> </div> <script type="text/javascript">// <![CDATA[ var data = [{ 'name':'word', 'child':[ { 'name':'A', 'child':[{ 'name':'Aa', 'child':[] },{ 'name':'Ab', 'child':[] }] },{ 'name':'B', 'child':[{ 'name':'Ba', 'child':[{ 'name':'Baa', 'child':[] }] },{ 'name':'Bb', 'child':[] }] },{ 'name':'C', 'child':[{ 'name':'Ca', 'child':[] },{ 'name':'Cb', 'child':[{ 'name':'Cba', 'child':[{ 'name':'Cbaa', 'child':[] }] }] }] } ] }] var container = document.getElementById('app'); function render(arr){ var oUl = document.createElement('ul'); arr.forEach(function(value, index, allArray){ var li = document.createElement('li'); li.innerHTML = value.name; oUl.appendChild(li); if(value.child.length>0){ var child = render(value.child); li.appendChild(child); } }); return oUl; } container.appendChild(render(data)); </script>
运行结果就是不同的级别都是一个ul列表,然后嵌套在父级的li中。
有了渲染方式,但是后端返回的数据不一定是上述格式,针对无序返回的列表(如下)做了一个无限极排序。
//返回的数据不同级别都放在一个列表中,其中有标示其级别父id自己id的信息,根据这些信息我们把它做成之前渲染所需要的数据格式。
"datalist": [{ "faccountname": "库存现金", "fcurrencynumber": " ", "fparentid": "0", "flevel": "1", "fdebit": "0.0000", "faccountid": "1001", "fdetailidorder": "0", "fdc": "1", "fendbalancefor": "0.0000", "fdetailid": "0", "fdetail": "True", "fbeginbalancefor": "0.0000", "fcredit": "0.0000", "fname": "库存现金", "fnumber": "1001" }, { "faccountname": "银行存款", "fcurrencynumber": " ", "fparentid": "0", "flevel": "2", "fdebit": "0.0000", "faccountid": "1002", "fdetailidorder": "0", "fdc": "1", "fendbalancefor": "0.0000", "fdetailid": "0", "fdetail": "False", "fbeginbalancefor": "0.0000", "fcredit": "0.0000", "fname": "银行存款", "fnumber": "1002" }]
直接上代码
var newArr = []; var obj = {}; //首先把不同级的数据分类,并添加childs属性,方便子集的插入 Data.datalist.forEach(function(item){ item.childs = []; //以级别为key定义对象数组,这里级别一般以数字为主方便在下面插入数组的时候自动排序 if(!obj[item.flevel]){ obj[item.flevel] = []; } //如果该级别已存在则直接添加到该级别数组 obj[item.flevel].push(item); }) //把数据插入数组 for(var item in obj){ newArr.push(obj[item]); } //倒序插入父级 var len = newArr.length; //由于是倒序所以使用while循环,避免for循环每次的比较 while(len){ insert(newArr[len], newArr[len-1]); len--; } function insert(child, parent){ //在这里先循环子集,在与对应的父级匹配之后break;减少父级循环 child.forEach(function(itemChild){ parent.forEach(function(itemParent){ if(itemChild.fparentid == itemParent.faccountid){ itemParent.childs.push(itemChild); break; } }) }) }
在这里做了尽可能的优化。可以直接上github拉代码测试: