后端没人性,前端无节操
Liber 2014-03-03 13:41

近日,有这么个事儿:
根据后端返回的一个数据List,生成一颗有层次的树形结构。

为什么说「后端没人性」呢?相信大家看了那个数据List之后就明白了。
至于「前端无节操」,是因为我用了一个递归的方法,实现了层次的无限级递归显示。

本文最大的价值在于:
提醒自己,处理很多问题的时候,别忘了想一想递归的方式,有时候并不像想象的那么复杂。

注:该示例中有很多地方是对实际需求中细节的处理,大家主要去看体现递归思想的核心部分即可。

代码一瞥:


  getTreeListFromListByLevels: function(list, levels, options) {
  
    var getObjFromItemAndOptionsAtLevels = function(item, options, levels) {
    
      var name = '';
      for(var i = levels.length - 1; i >= 0; i--) {
        if(item[levels[i]]) {
          name = item[levels[i]];
          break;
        }
      }
      var obj = {
        'name': name
      };
      
      _.each(options, function(value, key) {
        obj[key] = item[value];
      });
      
      return obj;
    };
    
    var isItemIsLeafAtLevels = function(item, levels) {
      var count = 0;
      for(var i = 1; i < levels.length; i++) {
        if(item[levels[i]]) {
          count++;
        }
      }
      return count <= 1 ? true : false;
    };
  
    var treeList = [];
    var levelList = _.filter(list, function(item) {
      return item[levels[0]];
    });
    
    var brokenList = _.filter(list, function(item) {
      return !item[levels[0]];
    });
    if(brokenList.length > 0) {
      _.each(this.getTreeListFromListByLevels(brokenList, levels.slice(1), options), function(objItem) {
        treeList.push(objItem);
      }, this);
    }
    
    if(levels[1]) {
      
      var uniqListArr = _.uniq(_.pluck(levelList, levels[0]));
      
      var branchList = _.filter(levelList, function(item) {
        return !isItemIsLeafAtLevels(item, levels);
      });
      var uniqBranchArr = _.uniq(_.pluck(branchList, levels[0]));
      
      var leafList = _.filter(levelList, function(item) {
        return isItemIsLeafAtLevels(item, levels);
      });
      
      _.each(uniqListArr, function(listItem) {
      
        var children = [];
        if(_.indexOf(uniqBranchArr, listItem) != -1) {
          var currentList = _.filter(branchList, function(item) {
            return item[levels[0]] === listItem;
          });
          children = this.getTreeListFromListByLevels(currentList, levels.slice(1), options);
        }
        var branchObj = {
          'name': listItem,
          'children': children,
          'open': false
        };
        treeList.push(branchObj);
        
        _.each(leafList, function(leafItem) {
          if(leafItem[levels[0]] === listItem) {
            branchObj.children.push(getObjFromItemAndOptionsAtLevels(leafItem, options, levels));
          }
        });
        
      }, this);
    
    } else {
    
      _.each(levelList, function(item) {
        treeList.push(getObjFromItemAndOptionsAtLevels(item, options, levels));
      });
      
    }
    
    return treeList;
  }
  

运行效果:

Source Download

后记:
zTree可以接受两种数据:

1. 标准JSON数据:


var nodes = [
	{name: "父节点1", children: [
		{name: "子节点1"},
		{name: "子节点2"}
	]}
];

2. 简单JSON数据:


var nodes = [
	{id:1, pId:0, name: "父节点1"},
	{id:11, pId:1, name: "子节点1"},
	{id:12, pId:1, name: "子节点2"}
];

我这里用的是前一种,事实上,用后一种方式处理起来会更简单。
看到别人用的第二种方式,顿时鄙视一下自己。总结起来,还是情报收集的不够充分,然后盲目动手造成的。