先来个图鉴赏一下:
网上不少关于 ztree 的应用,但是都是简单的功能demo, 真正做到异步加载并搜索的我没有搜索到,所以结合官方文档和网上demo自己做了一个。这可能是个笨方法,哪位童鞋有更好的方法欢迎探讨哦。
前端比较简单:
<div class="content-wrapper">
<section class="content-header">
<h1 CLASS="hidden-xs">
<small>hpo</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i> 主页</a></li>
<li class="active">hpo_tree</li>
</ol>
</section>
<section class="content">
<ul class="list">
<li class="title">表型搜索:
<input id="search_content" type="text" value="" name="param"/>
</li>
</ul>
<div class="row" id="menuContent">
<div class="col-xs-8">
<ul id="phenotype_tree" class="ztree"></ul>
</div>
</div>
</section>
</div>
var setting = {
view: {
selectedMulti: false
},
async: {
enable: true,
url: "/app/hpo_dtl/",
autoParam: ["id", "level"],
},
callback: {
onNodeCreated: zTreeOnNodeCreated
}
};
$(document).ready(function () {
$.fn.zTree.init($("#phenotype_tree"), setting);
});
$("#search_content").on('keypress', function (event) {
if (event.keyCode == 13) {
searchM();
}
});
function searchM() {
var param = $.trim($("input[name='param']").val());
var treeObj = $.fn.zTree.getZTreeObj("phenotype_tree");
var node = treeObj.getNodeByParam("id", 0, null);
if (param != "") {
treeObj.setting.async.otherParam = ["param", param];
} else {
//搜索参数为空时必须将参数数组设为空
treeObj.setting.async.otherParam = [];
}
treeObj.reAsyncChildNodes(node, "refresh");
}
function zTreeOnNodeCreated(event, treeId, treeNode) {
var param = $.trim($("input[name='param']").val());
var treeObj = $.fn.zTree.getZTreeObj("phenotype_tree");
//只有搜索参数不为空且该节点为父节点时才进行异步加载
if (param != "" && treeNode.isParent) {
treeObj.reAsyncChildNodes(treeNode, "refresh");
}
}
如此前端就完成了:
- 开启了 ztree 的异步加载
- 自动填充参数为 id 和 level
- 当按下回车的时候开始搜索
前面步骤就是 ztree 的基本使用:
- 后端接收默认 level 为 -1 ,返回所有顶层对象,并渲染。
- 当点击顶层对象前面的 + 的时候,传递 id 和 level 异步加载此时的顶层对象,如此反复迭代,做到了异步加载
搜索部分,点击搜索之后传递关键词到后端:
- 搜索到带有关键词的终端节点
- 根据父子关系依次搜索到次顶级节点,插入所有节点到结果中返回
- 前端 ztree 会再次发起搜索每个次顶级节点的关键词
- 如此反复迭代即可把带有关键词的整棵树搜索一遍
缺点:
- 一棵树反复迭代, 效率较低, 对后端并发响应是一个考验
- 遇到越简单的关键词搜索速度越慢
参考资料: