yylib-quick-mobile
Version:
yylib-quick-mobile
117 lines (115 loc) • 4.67 kB
JavaScript
/*树结构数据的相关操作工具方法*/
function getChildrenlength(children) {
let len = 1;
if (Array.isArray(children)) {
len = children.length;
}
return len;
}
function getSiblingPosition(index, len, siblingPosition) {
if (len === 1) {
siblingPosition.first = true;
siblingPosition.last = true;
} else {
siblingPosition.first = index === 0;
siblingPosition.last = index === len - 1;
}
return siblingPosition;
}
var TreeUtils = {
/**
* 遍历树结构子集对象
* @param childs {array} 需要遍历的树结构
* @param callback {function} 遍历时的回调函数,传递参数:item(当前结点)、index(当前索引)、pos(当前层级和索引)、key、siblingPos(兄弟节点间的索引)、parent
* @param parent {object} 当前父级节点
*/
loopAll:function(childs, callback, parent) {
const loop = (children, level, _parent) => {
const len = getChildrenlength(children);
children.forEach((item, index) => {
const pos = `${level}-${index}`;
if(item){
if (item.children&&item.children.constructor==Array) {
loop(item.children, pos, { node: item, pos });
}
callback(item, index, pos, item.key || pos, getSiblingPosition(index, len, {}), _parent);
}
});
};
loop(childs, 0, parent);
}
/**
* 查找树节点下指定节点属性值匹配的节点
* @param nodes {array} 子节点集合
* @param propName {string} 属性名
* @param propValue {*} 属性值
* @param loop{boolean} 默认:true,是否递归遍历子集合
* @param only{boolean} 默认:true,是否匹配到第一个就终止
* @param childPropName{boolean} 默认:children,子节点集合的属性名
*/
,findWithPropName:function(nodes,propName,propValue,loop,only,childPropName){
var _results = [];
var _nodes =(nodes&&nodes.constructor==Array)?nodes:[];
var _childPropName = childPropName?childPropName:'children';
for(var i=0;i<_nodes.length;i++){
var node = _nodes[i];
if(!node||typeof node!="object")continue;
if(node[propName]&&node[propName]==propValue){
_results.push(node);
if(only==undefined||only==true)break;
}
if(loop!=false&&node[_childPropName]&&node[_childPropName].length>0){
var currResults = this.findWithPropName(node[_childPropName],propName,propValue,loop,only,_childPropName);
if(currResults!=null){
_results=_results.concat(currResults);
}
}
}
return _results;
}
/**
* 移除树节点下指定节点属性值匹配的节点
* @param tree {object} 子节点集合
* @param propName {string} 属性名
* @param propValue {*} 属性值
* @param loop{boolean} 默认:true,是否递归遍历子集合
* @param childName 子集合的属性名
*/
,removeWithPropName:function(tree,propName,propValue,loop,childName="children"){
const doLoop = (data,propName,propVal, callback) => {
data.forEach((item, index, arr) => {
if (item[propName] === propVal) {
return callback(item, index, arr);
}
if (loop!=false&&(item[childName]&&item[childName].constructor==Array)) {
return doLoop(item[childName],propName,propVal, callback);
}
});
};
if(tree && propName && propValue){
doLoop((tree&&tree.constructor==Array)?tree:[tree],propName, propValue, function (item, index, arr) {
arr.splice(index, 1);
});
}
return tree;
}
/**
* 通过ID查找树节点
* @param nodes {array} 子节点集合
* @param idValue {*} ID属性值
*/
,findById:function(nodes,idValue){
var results = this.findWithPropName(nodes,'id',idValue,true,true);
return results.length>0?results[0]:null;
}
/**
* 删除树下对应ID的节点
* @param tree {object} 树结构对象
* @param nodeId {*} 树节点id
*/
,removeById:function(tree,nodeId){
var tree = this.removeWithPropName(tree,'id',nodeId,true);
return tree;
}
}
module.exports = TreeUtils;