最近在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; } }