記錄項(xiàng)目中關(guān)于ztree插件的使用伍纫。
實(shí)現(xiàn)的功能有:排序剩辟、遷移、搜索崇败、刪除晓锻、右鍵菜單歌焦、重命名、新增砚哆。
html代碼
html代碼非常簡單:具體的樣式找美工調(diào)整
搜索框
<input type="text" placeholder="搜索 ..." id="nav-search-input">
樹
<ul id="categoryTree" ></ul>
菜單
<div id="rMenu" >
<ul>
<li id="m_add" onclick="addTreeNode();">添加節(jié)點(diǎn)</li>
<li id="m_resetname" onclick="renameTreeNode();">重命名</li>
<li id="m_delete" onclick="removeTreeNode();">刪除節(jié)點(diǎn)</li>
<li id="m_allcate_administrator" onclick="allcateAdmin();">分配管理員</li>
<li id="m_allcate_download" onclick="allcateDownload();">下載權(quán)限配置</li>
</ul>
</div>
參數(shù)設(shè)置及數(shù)據(jù)加載
var setting = {
async: {
enable: true,//采用異步加載
url : "加載樹數(shù)據(jù)的url",
autoParam: ["id"],//自動提交的參數(shù)独撇,每次異步加載時(shí)都會附帶該參數(shù)
dataType : "json"http://返回json格式的數(shù)據(jù)
},
data : {
key : {},
simpleData : {
enable : true,//采用簡單數(shù)據(jù)格式
idKey : "id",//每個(gè)節(jié)點(diǎn)數(shù)據(jù)的id
//這里必須是pId,而不能寫成pid躁锁,Pid等形式纷铣,否則數(shù)據(jù)無法顯示
idPKey : "pId",
rootPid : "0"http://根節(jié)點(diǎn)的id
}
},
view : {
expandSpeed : "",//關(guān)閉動畫,否則搜索時(shí)頻繁開閉節(jié)點(diǎn)會使節(jié)點(diǎn)狀態(tài)錯(cuò)亂
fontCss : getFontCss,//設(shè)置字體:主要是搜索后對目標(biāo)節(jié)點(diǎn)著色處理
showIcon : true,
dblClickExpand : false,
selectedMulti : true,
addHoverDom: addHoverDom,
removeHoverDom: removeHoverDom
},
callback : {
onRightClick : OnRightClick,
onClick : zTreeOnClick,
//beforeRename : beforeRename,
//onRename : zTreeOnRename,
beforeDrag : beforeDrag,
beforeDrop : zTreeBeforeDrop
},
check : {
enable : false,
},
edit : {
drag : {
isCopy : false,//
isMove : true,//
prev : true,//允許移動到目標(biāo)節(jié)點(diǎn)前面
next : true,//允許移動到目標(biāo)節(jié)點(diǎn)后面
inner : true,//允許移動到目標(biāo)節(jié)點(diǎn)內(nèi)
},
enable : true,
showRemoveBtn : false,
showRenameBtn : false
}
};
var categoryTree = $.fn.zTree.init($("#categoryTree"), setting);
var rMenu = $("#rMenu");
右鍵的顯示與隱藏
這里是由于項(xiàng)目需要不同人員的權(quán)限不同战转,右鍵菜單選項(xiàng)不同搜立;如果你也有這種需求,我覺得這里有兩種實(shí)現(xiàn)方式槐秧,一是像這里寫的啄踊,點(diǎn)擊右鍵時(shí)去后代判斷,根據(jù)判斷結(jié)果再去顯示刁标;二是在獲取樹的信息的時(shí)候颠通,把判斷所需要的必要參數(shù)直接放在json里一塊返回來,這樣前臺只需要直接判斷就行了膀懈。
function OnRightClick(event, treeId, treeNode) {
categoryTree.selectNode(treeNode);
//后臺請求右鍵選項(xiàng)有哪些
$.ajax({
cache : true,
type : "POST",
url : "${root.contextPath!}/klcategory/rightClickCategory",
data : {
id : treeNode.id
},
async : false,
error : function(request) {},
success : function(data) {
//data是map類型顿锰,放了一些判斷右鍵菜單選項(xiàng)的參數(shù)
data = eval("(" + data + ")");
showRMenu(data, treeNode, event.clientX, event.clientY);
},
});
}
//彈出右鍵菜單
function showRMenu(data, treeNode, x, y) {
$("#rMenu").show();
var count = 0;
if(!data.canRename && !data.canAddCategoty
&& !data.canDelete && !data.canAllocateDownload
&& !data.canAllocateAdmin) {
$("#rMenu").hide();
}else{
$("#rMenu").show();
$("#rMenu ul").show();
if(data.canRename){
$("#m_resetname").show();
count +=1
}else{
$("#m_resetname").hide();
}
if(data.canAddCategoty){
$("#m_add").show();
count +=1
}else{
$("#m_add").hide();
}
if(data.canDelete){
$("#m_delete").show();
count +=1
}else{
$("#m_delete").hide();
}
if(data.canAllocateDownload){
$("#m_allcate_download").show();
count +=1
}else{
$("#m_allcate_download").hide();
}
if(data.canAllocateAdmin){
$("#m_allcate_administrator").show();
count +=1
}else{
$("#m_allcate_administrator").hide();
}
}
//判斷菜單會不會溢出窗口,如果溢出就改成上浮
//這是由于樹的信息很多启搂,有時(shí)右鍵菜單顯示的時(shí)候硼控,可能會溢出瀏覽器。
//所以做了一下處理胳赌。這里的33是每個(gè)菜單選項(xiàng)的高度值(單位px)
//需要根據(jù)你實(shí)際項(xiàng)目中的值再設(shè)定牢撼。
if($(window).height() - y < 33*count){
y = y - 33*count;
}
rMenu.css({
"top" : y + "px",
"left" : x + "px",
"visibility" : "visible"
});
$("body").bind("mousedown", onBodyMouseDown);
}
//隱藏右鍵菜單
function hideRMenu() {
if (rMenu)
rMenu.css({
"visibility" : "hidden"
});
$("body").unbind("mousedown", onBodyMouseDown);
}
//鼠標(biāo)在非右鍵菜單位置點(diǎn)擊時(shí),隱藏菜單
function onBodyMouseDown(event) {
if (!(event.target.id == "rMenu"
|| $(event.target).parents("#rMenu").length > 0)) {
rMenu.css({
"visibility" : "hidden"
});
}
}
//點(diǎn)擊樹后的回調(diào):選中當(dāng)前節(jié)點(diǎn)
function zTreeOnClick(event, treeId, treeNode) {
categoryTree.selectNode(treeNode);
//這里可以根據(jù)需要匈织,添加其他事件浪默。
};
重命名 / 刪除 / 新增
function renameTreeNode(){
//這里有兩種實(shí)現(xiàn)方式:
(1)直接調(diào)用ztree的editName()牡直,使節(jié)點(diǎn)進(jìn)入可編輯狀態(tài)。
命名之后再實(shí)現(xiàn)ztree的回調(diào)函數(shù)onRename纳决,去后臺更新數(shù)據(jù)碰逸;
(2)彈出對話框,在其中進(jìn)行重命名阔加,后臺更新數(shù)據(jù)完成之后饵史。
再設(shè)置該節(jié)點(diǎn)的name屬性,調(diào)用樹的updateNode方法進(jìn)行更新樹上的節(jié)點(diǎn)數(shù)據(jù)胜榔。
}
//---------------------------------刪除節(jié)點(diǎn)------------------------------
function removeTreeNode() {
var nodes = categoryTree.getSelectedNodes();
//這里要進(jìn)行后臺的刪除胳喷,后代刪除成功后調(diào)用下面的方法刪除
//categoryTree.removeNode(nodes[0]);
}
//----------------------------------新增節(jié)點(diǎn)--------------------------------------------------
function addTreeNode(){
//與重命名類似,實(shí)現(xiàn)方式有兩種
(1)調(diào)用數(shù)的addNodes方法夭织,再去后臺執(zhí)行邏輯
(2)彈出對話框先去后臺執(zhí)行邏輯吭露,后臺增加成功后,去刷新新增目錄的直接父節(jié)點(diǎn)尊惰。
(調(diào)用reAsyncChildNodes,但要注意的是讲竿,如果父節(jié)點(diǎn)的isParent屬性是false的話,
該方法是不會執(zhí)行的弄屡,記得在調(diào)用reAsyncChildNodes之前先用ztree的updateNode
方法更新父節(jié)點(diǎn)的isParent屬性為true)题禀;或者addNodes直接在樹上添加節(jié)點(diǎn)
}
節(jié)點(diǎn)的檢索
實(shí)現(xiàn)的效果是:輸入框內(nèi)只要有輸入變化,就會執(zhí)行一次搜索方法
火狐有一個(gè)bug膀捷,就是假如樹中含有一個(gè)名字為“haha”的節(jié)點(diǎn)和名字為“哈哈”的節(jié)點(diǎn)迈嘹,這時(shí)你用中文輸入法去打“哈”這個(gè)字,發(fā)現(xiàn)只能輸入英文全庸。秀仲。扯遠(yuǎn)了,當(dāng)然這個(gè)可以不做糕篇。重點(diǎn)是搜索方法啄育。
其實(shí)獲取到含有搜索關(guān)鍵字的所有節(jié)點(diǎn)很簡單酌心,ztree已經(jīng)封裝好了拌消,就是getNodesByParamFuzzy()。
但是安券,想要的效果是墩崩,執(zhí)行下一次搜索時(shí),要把上一次搜索展開的節(jié)點(diǎn)全都關(guān)閉侯勉,再去展開這種的符合條件的節(jié)點(diǎn)鹦筹。
按道理講,也很簡單址貌,調(diào)用expandAll(false)就可以將節(jié)點(diǎn)都關(guān)閉铐拐,然后再去展開符合條件的節(jié)點(diǎn)就行了徘键。
但是這樣寫了以后,發(fā)現(xiàn)上次搜索展開的節(jié)點(diǎn)并不會全部關(guān)閉遍蟋,而是有的關(guān)閉了吹害,有的還是展開的。
在網(wǎng)上搜了很久虚青,在ztree的github項(xiàng)目的issue中找到了一點(diǎn)線索它呀,說展開和關(guān)閉都是有動畫的。
我想可能是前面的關(guān)閉所有節(jié)點(diǎn)還沒有執(zhí)行完棒厘,與后面的展開節(jié)點(diǎn)沖突了纵穿。
于是就去api里找,發(fā)現(xiàn)有expandSpeed這個(gè)參數(shù)設(shè)置奢人,將動畫關(guān)閉谓媒,這個(gè)bug竟然好了。
具體的關(guān)于dom的內(nèi)部原理我不了解何乎。
//輸入框內(nèi)獲取焦點(diǎn)時(shí)按回車執(zhí)行搜索篙耗,并屏蔽掉后續(xù)事件(提交表單等)
$("#nav-search-input").focus(function() {
//輸入框內(nèi)容變化時(shí)執(zhí)行搜索
var userAgent = navigator.userAgent; //取得瀏覽器的userAgent字符串
if (userAgent.indexOf("Firefox") > -1) {//單獨(dú)對Firefox瀏覽器
var node = document.querySelector('#nav-search-input');
var cpLock = false;
node.addEventListener('compositionstart', function(){
cpLock = true;
});
node.addEventListener('compositionend', function(){
cpLock = false;
});
node.addEventListener('input', function(){
if(!cpLock){
categorySearch();
$("#nav-search-input").focus();
}
});
}else{
$("#nav-search-input").bind('input propertychange', function() {
categorySearch();
$("#nav-search-input").focus();
});
}
$("#nav-search-input").keypress(function(e) {
var key = window.event ? e.keyCode : e.which;
if (key.toString() == "13") {
categorySearch();
return false;
}
});
});
//關(guān)于節(jié)點(diǎn)檢索,只看這個(gè)方法就行了宪赶。
function categorySearch() {
//收起所有節(jié)點(diǎn)
categoryTree.expandAll(false);
//獲取所有節(jié)點(diǎn)
var allNodes = getAllNodes();
//將所有節(jié)點(diǎn)不著色
$(allNodes).each(function() {
this.highlight = false;
categoryTree.updateNode(this);
});
//清除選中狀態(tài)
$(allNodes).each(function() {
categoryTree.cancelSelectedNode(this);
});
//獲取輸入的內(nèi)容
var searchContent = $("#nav-search-input").val();
//如果節(jié)點(diǎn)中含有搜索內(nèi)容宗弯,就展開其父節(jié)點(diǎn),并選中當(dāng)前節(jié)點(diǎn)
if (searchContent.length > 0) {
//獲取包含搜索內(nèi)容的節(jié)點(diǎn)
var nodes = categoryTree.getNodesByParamFuzzy("name",
searchContent, null);
//對包含搜索內(nèi)容的節(jié)點(diǎn)著色和展開
$(nodes).each(
function() {
categoryTree.selectNode(this, true, true);
this.highlight = true;
categoryTree.updateNode(this);
categoryTree.expandNode(this.getParentNode(), true,
false, true);
});
}
}
//獲取所有節(jié)點(diǎn)數(shù)據(jù)
function getAllNodes() {
//這個(gè)方法僅僅獲取所有根節(jié)點(diǎn)
var rootNodes = categoryTree.getNodes();
//這樣才可以獲取到所有節(jié)點(diǎn)
return categoryTree.transformToArray(rootNodes);
}
//設(shè)置字體顏色
function getFontCss(treeId, treeNode) {
return (!!treeNode.highlight) ? {
color : "#A60000",
"font-weight" : "bold"
} : {
color : "#333",
"font-weight" : "normal"
};
}
節(jié)點(diǎn)的遷移(包含了排序)
//遷移節(jié)點(diǎn)前執(zhí)行的操作:主要是對權(quán)限的處理
//項(xiàng)目中搂妻,有些節(jié)點(diǎn)不能遷移蒙保。如果是隨意移動的話,可以不看這個(gè)方法欲主。
var moveType;//節(jié)點(diǎn)移動類型:prev/next/inner
function beforeDrag(treeId, treeNodes) {
//獲取拖拽節(jié)點(diǎn)的根節(jié)點(diǎn)
dragNodeRoot = treeNodes[0];
for (var i = 0; i < treeNodes.length; i++) {
if (treeNodes[i].id.length < dragNodeRoot.id.length) {
dragNodeRoot = treeNodes[i];
}
}
//記錄原來遷移節(jié)點(diǎn)的最上層節(jié)點(diǎn)的父節(jié)點(diǎn)/相鄰節(jié)點(diǎn)邓厕,便于回撤遷移操作
dragNodeRootParent = dragNodeRoot.getParentNode();
dragNodeRootPrev = dragNodeRoot.getPreNode();
dragNodeRootNext = dragNodeRoot.getNextNode();
//如果是一級節(jié)點(diǎn),不能遷移
if (如果是一級節(jié)點(diǎn)) {
return false;
}
//如果不是該節(jié)點(diǎn)的管理員扁瓢,不能遷移
if (不是該節(jié)點(diǎn)的管理員) {
return false;
}
curDragNodes = treeNodes;
return true;
}
//遷移節(jié)點(diǎn)時(shí)详恼,釋放節(jié)點(diǎn)時(shí)的操作:同樣進(jìn)行了權(quán)限的處理
function zTreeBeforeDrop(treeId, treeNodes, targetNode, moveType, isCopy) {
//不允許遷移成一級節(jié)點(diǎn)
if(moveType != "inner" && targetNode是一級節(jié)點(diǎn) ){
return false;
}
return true;
后代執(zhí)行遷移的操作:
后臺成功:
//刷新樹上節(jié)點(diǎn)的id和pid信息
if(moveType == "inner"){
categoryTree.reAsyncChildNodes(targetNode, "refresh");
}else{
categoryTree.reAsyncChildNodes(targetNode.getParentNode(), "refresh");
}
后臺失敗:
moveNodeBack();
}
function moveNodeBack() {
if(dragNodeRootPrev != null){
categoryTree.moveNode(dragNodeRootPrev, dragNodeRoot, "next");
}else if(dragNodeRootNext != null){
categoryTree.moveNode(dragNodeRootNext, dragNodeRoot, "prev");
}else {
categoryTree.moveNode(dragNodeRootParent, dragNodeRoot, "inner");
}
}
右鍵其他菜單選項(xiàng)
function allcateAdmin() {
//.............這里是右鍵其他選項(xiàng)的功能
}
function allcateDownload() {
//.............這里是右鍵其他選項(xiàng)的功能
}
鼠標(biāo)移入移出事件
這里實(shí)現(xiàn)的效果是:鼠標(biāo)移動到某個(gè)節(jié)點(diǎn)上時(shí)引几,節(jié)點(diǎn)后面會出現(xiàn)一個(gè)圖標(biāo)昧互,點(diǎn)擊圖標(biāo),實(shí)現(xiàn)something
//鼠標(biāo)移入事件
var IDMark_A = "_a";// 拼裝獲取樹節(jié)點(diǎn)a鏈接id
function addHoverDom(treeId, treeNode) {
if (treeNode.parentNode && treeNode.parentNode.id!=1) return;
var aObj = $("#" + treeNode.tId + IDMark_A);
var ico = document.getElementById(treeNode.tId+"_ico").style.backgroundImage;
if ($("#addBtn_"+treeNode.id).length>0) {
return;
}else{
var flag = (ico.indexOf("project")==-1);
if(flag){
var editStr = "<img width='12' height='12' style='margin-left:7px;' title='增加' src='${root.contextPath!}/resource/images/kd_add.png' id='addBtn_" +treeNode.id+ "' title='"+treeNode.name+"' onfocus='this.blur();'>";
aObj.append(editStr);
var addbtn = $("#addBtn_"+treeNode.id);
if (addbtn) {
addbtn.bind("click", function(event){
dosomething(event, treeNode);
});
}
}
}
}
//鼠標(biāo)移出節(jié)點(diǎn)事件——開始
function removeHoverDom(treeId, treeNode) {
if (treeNode.parentNode && treeNode.parentNode.id!=1) return;
$("#addBtn_"+treeNode.id).unbind().remove();
}
function dosomething(event, treeNode) {
}
```
---
### 關(guān)于排序
排序其實(shí)就是節(jié)點(diǎn)的兩種拖拽類型:拖到節(jié)點(diǎn)之后伟桅,拖到節(jié)點(diǎn)之前敞掘。主要是后臺在處理的時(shí)候。
項(xiàng)目中的實(shí)現(xiàn)思路是:
(1)對每個(gè)節(jié)點(diǎn)數(shù)據(jù)楣铁,設(shè)置一個(gè)排序號字段玖雁;
(2)同一級的節(jié)點(diǎn)按排序號進(jìn)行排序;
(3)拖拽節(jié)點(diǎn)之后盖腕,更新相關(guān)節(jié)點(diǎn)的排序號赫冬,以及對應(yīng)的父子關(guān)系浓镜。
還有一點(diǎn),在讀取樹信息的時(shí)候劲厌,將節(jié)點(diǎn)按節(jié)點(diǎn)排序號排序之后竖哩,再放在json里面。對同一級的節(jié)點(diǎn)來說脊僚,樹的節(jié)點(diǎn)的顯示順序是按照json里的節(jié)點(diǎn)存放順序排列的相叁。
舉個(gè)例子:下面兩種json對象排列順序,顯示出來排列結(jié)果是一樣的
```
[{ id:1, pId:0, name:"植物"},
{ id:2, pId:0, name:"動物"},
{ id:3, pId:2, name:"大象"},
{ id:4, pId:2, name:"鯊魚"},
{ id:5, pId:1, name:"大白菜"},
{ id:6, pId:1, name:"西紅柿"}];
[{ id:1, pId:0, name:"植物"},
{ id:3, pId:2, name:"大象"},
{ id:5, pId:1, name:"大白菜"},
{ id:4, pId:2, name:"鯊魚"},
{ id:2, pId:0, name:"動物"},
{ id:6, pId:1, name:"西紅柿"}];
兩種寫法的顯示效果都是下面這樣:
植物
大白菜
西紅寺
動物
大象
鯊魚
```
---
### 后臺獲取樹信息的java代碼
```
項(xiàng)目中采用的是SpringMVC框架辽幌,@ResponseBody注解是必須的增淹,
將獲取信息直接寫到response中
ztree的配置如下:
url : "加載樹數(shù)據(jù)的url",
autoParam: ["id"],//第一次提交會這個(gè)id是空,之后點(diǎn)擊節(jié)點(diǎn)乌企,如果該節(jié)點(diǎn)是父節(jié)點(diǎn)虑润,并且還沒有加載直接子級的信息,那么就會提交該節(jié)點(diǎn)的id加酵。
@RequestMapping(value = "/categoryTreeInfo", method = RequestMethod.POST)
@ResponseBody
public void getCategoryTreeInfo(Integer id, HttpServletRequest request,HttpServletResponse response) {
try {
JSONArray jsonArr = new JSONArray();
response.setCharacterEncoding("utf-8");
response.setContentType("text/json");
// 獲取目錄信息
if (null == id) {//可以理解為根節(jié)點(diǎn)的id為1
id = 1;
}
//獲取節(jié)點(diǎn)的直接子級節(jié)點(diǎn)的信息拳喻,這里要注意,對同一級目錄而言猪腕,它的顯示順序跟放在json里的前后順序是一致的冗澈,所以在這個(gè)方法getDirectChildCategoryById(id)的實(shí)現(xiàn)里,要按照自己想要的順序陋葡,寫sql的時(shí)候亚亲,order by 一下。
List<Category> categoryList = categoryServiceImpl.getDirectChildCategoryById(id);
// 將信息組成樹需要的JSON對象
User user = super.getLoginUser();
//遞歸獲取所有節(jié)點(diǎn)信息
getCategoryTreeJson(user, jsonArr, categoryList, id);
response.getWriter().print(jsonArr.toString());
// 也可以在獲取到所有的json數(shù)據(jù)后腐缤,針對某一字段進(jìn)行排序
//JSONArray jsonArray = sortJsonArray(jsonArr);
//logger.info("獲取到的目錄樹信息共" + jsonArr.size() + "個(gè):" + jsonArr.toString());
//return jsonArray.toString();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 功能說明:封裝目錄樹
*
* @param rootURL
* @param jsonArr
* @param categoryList
* @param id
*
*/
private void getCategoryTreeJson(User user, JSONArray jsonArr, List<Category> categoryList, Integer id) {
for (int i = 0; i < categoryList.size(); i++) {
JSONObject json = new JSONObject();
json.put("id", categoryList.get(i).getId());
json.put("name", categoryList.get(i).getName());
//這里key關(guān)鍵字必須是pId,不能是pid或者其他捌归,否則會出現(xiàn)open屬性失效等問題
json.put("pId", categoryList.get(i).getParent_id());
json.put("isFirst", categoryList.get(i).getParent_id()==1 ? 1 :0);
json.put("order", categoryList.get(i).getSort_number());
//獲取當(dāng)前用戶是否是該目錄的管理員:目錄遷移的時(shí)候用到這個(gè)參數(shù)
boolean isAdministrator = categoryServiceImpl.
isCategoryAdmin(categoryList.get(i).getId(), super.getLoginUser().getId());
if(isAdministrator){
json.put("administrator", 1);
}else {
json.put("administrator", 0);
}
// 判斷是否為父級
List<Category> childOrgList = categoryServiceImpl.getDirectChildCategoryById(categoryList.get(i).getId());
if (childOrgList != null && childOrgList.size() > 0) {
json.put("isParent", true);
//json.put("open", true);
//遞歸,獲取所有目錄信息
getCategoryTreeJson(user, jsonArr, childOrgList, categoryList.get(i).getId());
}
jsonArr.add(json);
}
}
/**
* 功能說明:對JSONArray排序
* 對于ztree來說岭粤,只要同級節(jié)點(diǎn)的順序排成你想要的效果就可以了惜索,不同
*級的節(jié)點(diǎn)順序不用處理
* @param jsonArr
* @return
*
*/
private JSONArray sortJsonArray(JSONArray jsonArr) {
JSONArray sortedJsonArray = new JSONArray();
List<JSONObject> jsonValues = new ArrayList<JSONObject>();
for (int i = 0; i < jsonArr.size(); i++) {
jsonValues.add(jsonArr.getJSONObject(i));
}
Collections.sort(jsonValues, new Comparator<JSONObject>() {
//這里,order是我json對象里的一個(gè)屬性剃浇,我要按這個(gè)排序巾兆。也可以按照id、name等你想要的屬性進(jìn)行排序
private static final String KEY_NAME = "order";
@Override
public int compare(JSONObject a, JSONObject b) {
long valA = 0;
long valB = 0;
try {
valA = (Integer) a.get(KEY_NAME);
valB = (Integer) b.get(KEY_NAME);
} catch (Exception e) {
e.printStackTrace();
}
if (valB > valA) {
return -1;
} else {
return 1;
}
}
});
for (int i = 0; i < jsonArr.size(); i++) {
sortedJsonArray.add(jsonValues.get(i));
}
return sortedJsonArray;
}
```
### 還有一點(diǎn)
搜索的時(shí)候偿渡,對還沒有加載的節(jié)點(diǎn)臼寄,是搜索不到的。
所以溜宽,如果要做搜索節(jié)點(diǎn)功能,就要在第一次加載樹信息的時(shí)候质帅,將所有節(jié)點(diǎn)全部獲取适揉。
但異步加載還是要配置成enable留攒,因?yàn)樵趯溥M(jìn)行排序、刪除嫉嘀、新增以及一些其他操作后炼邀,節(jié)點(diǎn)的信息很可能需要從后臺獲取才能完整的更新。
這時(shí)就要調(diào)用reAsyncChildNodes方法剪侮,而該方法只有在setting.async.enable = true 時(shí)有效拭宁。
---
### 最后一點(diǎn)
幾乎所有對樹節(jié)點(diǎn)的操作,都可以在ztree的api中找到相應(yīng)的方法瓣俯,
也可以在相應(yīng)的demo中找到例子杰标。