今天是17年的倒数第二天,明天就是跨年夜,17年末尾给小伙伴们分享一个小工具。
平时我们经常会遇到这样的需求,一个对象数组,对象中的每一项通过id和pid形成父子关系,我们需要取出某一个id节点下的所以子节点形成一个又父子关系层级的新对象;或者取出某一个id节点在整个节点树中的path路径,即父子层级上的关系,类似于面包屑导航。可能说的比较乱,还是用数据说话:
我们有这么一个data数组,可能是spa的路由管理;
var data = [
{id:122,pid:12,name:"模块2/子模块2"},
{id:11,pid:1,name:"模块1"},
{id:12,pid:1,name:"模块2"},
{id:13,pid:1,name:"模块3"},
{id:1,pid:0,name:"根节点"},
{id:111,pid:11,name:"模块1/子模块1"},
{id:121,pid:12,name:"模块2/子模块1"}
];
这个时候需要得到每个页面的面包屑导航和该路由下的自路由信息
//属性菜单生成逻辑demo
function Tree(arr){
if(arr && arr instanceof Array){
this._arr = arr;
this._arrMap = {};
//首先将节点信息遍历一遍,放到一个Map里,便于后续检索
for(var i=0; i<arr.length; i++){
var n = arr[i];
if(n && n.id){
this._arrMap[n.id] = n;
}
}
//建立父子关系
for(var i=0; i<arr.length; i++){
var n = arr[i];
var p = this._arrMap[n.pid];
if(p){
p.children = p.children || [];
p.children.push(n);
}
}
}
}
Tree.prototype={
constructor:Tree,
//获得以某一个节点信息,其中已经包含了所有树状关系。本节点的子菜单在节点的children属性里
getNode : function(rootid){
return this._arrMap[rootid];
},
//获得某一个节点从根点到此节点的路径
getPath : function(id){
var _a = [];
//当前节点
var _currentNode = this._arrMap[id];
while (_currentNode){
_a.unshift(_currentNode);
_currentNode = this._arrMap[_currentNode.pid];
}
return _a;
}
}
//测试
var data = [
{id:122,pid:12,name:"模块2/子模块2"},
{id:11,pid:1,name:"模块1"},
{id:12,pid:1,name:"模块2"},
{id:13,pid:1,name:"模块3"},
{id:1,pid:0,name:"根节点"},
{id:111,pid:11,name:"模块1/子模块1"},
{id:121,pid:12,name:"模块2/子模块1"}
];
var tree = new Tree(data);
console.info(tree);
//获得节点信息
console.info(tree.getNode(1));
console.info(tree.getNode(12));
console.info(tree.getNode(14));
//获得节点路径
console.info(tree.getPath(1));
console.info(tree.getPath(121));
console.info(tree.getPath(1211));
到这里,相信小伙伴们也已经从我拙劣的文字里明白该怎么用了吧,希望能帮到大家。
created by 子非鱼