最近在工作中使用到了jq中的zTree组件实现树形结构展示,记录一下使用中遇到的问题,以及我遇到的奇怪需求的解法。
官方Demo文档(内含API文档):Demo [zTree -- jQuery tree plug-ins.]
1、自定义节点样式,在执行回调函数后失效:
问题原因及个人猜想:这个问题很怪,在官方文档中说明了通过在setting中设置addDiyDom方法即可实现自定义控件,我想也没想,直接用上,结果在实际运行中却发现,本来定义好的节点在我点击后直接回到解放前。针对这个问题我在网上也没有找到确切的回答,所以个人猜测可能是zTree在执行回调函数时会重新加载整个zTree,对其进行刷新,但并没有使用开发者自定义的addDiyDom方法,所以导致发生了进行点击之后自定义样式消失的问题。
我的解决方案:在网上找了一圈并没有找到解决方案后,我决定使用最简单的办法,在每次执行回调函数的时候,给zTree重新进行节点的自定义,话不多说,直接上代码
//方法调用
ztreeInitView(tree.getNodes())
function ztreeInitView(treeNodes) {
for (let i = 0; i < treeNodes.length; i++) {
let spanObj = $("#" + treeNodes[i].tId + "_span");
let html = '';
if(treeNodes[i].fallNum > 0 || treeNodes[i].midNum > 0 || treeNodes[i].highNum > 0 || treeNodes[i].lowNum > 0) {
html += '<img src="' + webroot + '/img/assetFound/asset-warning.png" style="border:0"/>';
}
html += treeNodes[i].name +"<em>[ <span>" + treeNodes[i].total + "</span> ]</em>";
spanObj.html(html);
if(treeNodes[i].children.length != 0) {
ztreeInitView(treeNodes[i].children);
}
}
}
通过一个简单的递归实现zTree节点的自定义样式,啊哈,不愧是我。但很快我就迎来了第二个问题……
2、实现点击父节点,其子节点无法被选中(但是需要有选中样式,父节点取消选中后,子节点的选中效果也去除),再次选中只能选择除被选择父节点和其子节点的其他节点
其实这个需求乍一看也还行哈,但问题是,我们需要使用单选框实现这个功能,zTree本身自己是有复选框的,虽然也和我们的需求不太一样,但改一改也行对吧,但是!我们需要使用单选框实现这个功能……行吧,我写!
于是我修改了上面的递归函数进行了“简单”修改后得到了以下代码
function ztreeInitView(treeNodes, isChecked, type, checkNodeList) {
for (let i = 0; i < treeNodes.length; i++) {
let num = 0;
if(!isChecked && treeNodes[i].checked && type == 0) {
for (let j = 0; j < checkNodeList.length; j++) {
if(checkNodeList[j].id == treeNodes[i].id) {
num = 1;
break;
}
}
if(num == 0) {
treeNodes[i].checked = false;
}
} else {
treeNodes[i].checked = isChecked;
}
let spanObj = $("#" + treeNodes[i].tId + "_span");
let html = '';
if(treeNodes[i].fallNum > 0 || treeNodes[i].midNum > 0 || treeNodes[i].highNum > 0 || treeNodes[i].lowNum > 0) {
html += '<img src="' + webroot + '/img/assetFound/asset-warning.png" style="border:0"/>';
}
html += treeNodes[i].name +"<em>[ <span>" + treeNodes[i].total + "</span> ]</em>";
spanObj.html(html);
spanObj.attr("title", treeNodes[i].name + '[' + treeNodes[i].total + ']')
if(treeNodes[i].children.length != 0) {
ztreeInitView(treeNodes[i].children, treeNodes[i].checked, type, num == 0 ? checkNodeList : treeNodes[i].children);
}
}
}
这次在递归方法中添加了三个参数,第一个isChecked,是父节点是否被选中;第二个type,是当前状态,父节点被选中了还是被取消选中了;第三个checkNodeList,是哪一个子节点组需要被全选中。
在调用完此方法后记得执行refresh刷新方法,不然选中框是不会出现选中效果的。
如果是不可选中的子节点那么我们需要另做处理
if(treeNode.id != -1 && tree.getNodeByTId(treeNode.parentTId).checked) {
treeNode.checked = true;
tree.refresh();
}
以上就是本次使用zTree的记录,如果有更好的解决方案或者存在描述不对的地方欢迎评论或者私信我,Thanks♪(・ω・)ノ