最近在項目中遇到一個問題,需求如下:
根據選中不同的人員(ID)向后台發送ajax請求,通過返回的數據來生成該人員的權限訪問樹,該樹目錄最少為3級目錄,在生成的時候會自動勾選上次保存過的選中狀態,點擊保存后會將選中狀態發送給后端用於保存。(zTree的api參考網站http://www.ztree.me/v3/api.php)
遇到的bug:
用戶必須再次點擊已選中的根目錄,並重新選中一次才能在保存的時候將其根目錄及所有選中的子節點ID號提供給后端,如果用戶不做任何操作直接點擊保存,則只能獲取到根目錄的ID號,無法獲取其下所有子目錄和節點的ID號。
原因分析:
由於樹的生成采用的是異步加載方式,即一開始只生成所有的根目錄,用戶必須點擊某一條根目錄展開才會生成其下的子目錄或子節點。這樣可以減少初步加載時的響應時間,但是如果用戶不去點擊展開,那么系統默認的是沒有子節點的,因此在點擊保存時只能獲得選中的根目錄ID號。
解決方式:
在zTree的setting設置中將生成樹時的回調函數里添加zTree.expandAll(false)(展開或折疊所有的節點樹)。這樣插件就會遍歷生成所有的節點,並根據保存的選中ID來將對於的節點勾選。
callback : {//控制插件中所有的回調函數觸發
onClick : zTreeOnClick,//點擊時的回調函數
onNodeCreated: zTreeOnNodeCreated,//這是節點生成時的回調函數
onAsyncSuccess:showTree//異步加載成功完成后的回調函數
}
//其方法為根據data返回的選中ID來將對應的節點勾選
function zTreeOnNodeCreated(event, treeId, treeNode) {
var zTree = $.fn.zTree.getZTreeObj("tree");
$.post("renyxx/getQuanx",{id:$("#renyxxb_id").val()},function(data){
for(var i = 0;i < data[0].length;i++){
if(data[0][i]==treeNode.id){
treeNode.checked = true;
//zTree.expandAll(false);
zTree.updateNode(treeNode);
}
}
},"json");
zTree.expandAll(false);//加入這行代碼后,其就會在生成每一個根目錄時自動遍歷其下的所有子目錄或節點
}
大家可以在回調函數中加入console來看一下插件生成時的運行順序,並不是一次生成所有的根目錄,而是一個個的生成。
另外,這樣生成的樹只有最開始的一個根目錄,很難看,一般都會要求至少展開一級,因此可以在回調函數中添加onAsyncSuccess,在異步加載完成時會執行如下方法
function showTree(event, treeId, treeNode) { var zTree = $.fn.zTree.getZTreeObj("tree"); var tree=zTree.getNodeByTId("tree_1"); zTree.expandNode(tree,true);//展開指定的根目錄 }
