最近在zTree的使用上遇到了点问题,调完后特别在这记录下。
项目上要求的功能是实现对树节点的搜索功能,之前实现的方式是对树的节点遍历,筛选出符合的搜索条件的节点,然后重新生成一棵树。
但是对于数据量比较大的数而言,这种做法并不可取。
在看到了zTree的exhide这个拓展包后,我决定用hideNodes和showNodes来实现这个方法。
实现方式是:先将原先的Node通过hideNodes全部隐藏,然后再根据搜索条件过滤出符合条件的nodes,调用showNodes显示,但是树的节点无法正常显示。
搜索后:
调了很久才发现如果父节点是hide的话,那么即使子节点是显示的,这个子节点也无法被正常显示出来。(可能是之前的重新生成树的做法让我没想到这一点)
于是改了改代码,功能就正常了:
//点击查询按钮 $(document).off("click","#searchNode").on("click","#searchNode",function(){ var zTree = $.fn.zTree.getZTreeObj("treePanel"); //显示隐藏的节点 nodes = zTree.getNodesByParam("isHidden", true); zTree.showNodes(nodes); var root = zTree.getNodeByParam("level", "0"); var hiddenNodes = new Array(); //筛选出要隐藏的企业 var inputStr = $('#inputStr').val(); filterNodes(root, inputStr, hiddenNodes); zTree.hideNodes(hiddenNodes); });
因为同时筛选出父节点的过程比较复杂,不能简单使用一个filter函数就解决,于是我自己写了一个遍历树的方法进行筛选。
用了递归的实现,如果树的层次比较深的话,可能栈会吃不消,请根据具体情况使用。
/** * 遍历树节点,将 * 1.自身不满足搜索条件 * 且 * 2.其子节点不包含有满足条件的节点 * 的节点加入到filterResult中 * * @param node 查询的节点 * @param inputStr 搜索条件 * @param filterResult 过滤的结果集 * @return 该节点是否满足条件 */ function filterNodes(node, inputStr, filterResult){ if(node != null){ //自身是否符合搜索条件 var selfMatch = node.name.indexOf(inputStr) > -1; //子节点是否有满足的条件的节点 var childMatch = false; var children = node.children; if(children != undefined){ for(index in children){ childMatch = filterNodes(children[index], inputStr, filterResult) || childMatch; } } //自身不满足搜索条件 且其子节点不包含有满足条件的节点 if(!selfMatch && !childMatch){ filterResult.push(node); } return selfMatch || childMatch; }else{ return true; } }