简介
当你采用了异步加载,逐层加载节点的功能后,新增节点时,一定会先用 ajax 提交给后台进行保存,保存后再执行 addNodes 方法让树添加节点。然后问题就来了——怎么有时候会出现两个相同的新节点呢???
看这篇文档时,你需要对照 API 文档进行学习(http://www.treejs.cn/v3/api.php)
原因分析
了解过 zTree 的异步加载模式(04 章)后,应该会知道:zTree 展开父节点时,如果该父节点还没有加载子节点,那么就会自动触发异步加载。当你执行 addNodes 的时候,代码的执行过程是这样的:
对照上面这个流程图, 当你先用 ajax 让服务端添加节点后,在 异步加载子节点 的流程时,会把新增的节点从服务端带过来并加入 zTree;同时,在树上添加节点 的操作会把新增节点在树上又添加一遍。
解决方案
下面这段 Demo 的代码取自上一篇 7.05 如何使用自定义图层编辑节点属性 中提交表单的部分,因为使用 setTimeout 模拟 ajax 的异步过程,所以你只需要吧 setTimeout 里面的 function 想象成 ajax 的 success 回调函数即可。
function submitNewNode() {
var nodeName = nodeNameObj.val();
var nodeInfo = nodeInfoObj.val();
if (nodeName.length === 0) {
alert('名称不允许为空!');
return;
}
setTimeout(function() {
if (newNodeLayer.addNode) {
// 根据 zAsync 属性判断 父节点是否进行过异步加载
if (newNodeLayer.curNode.zAsync) {
// 如果父节点已经进行过异步加载,直接使用 addNodes 方法添加新节点
zTreeObj.addNodes(newNodeLayer.curNode, {
id: (100 + newCount),
pId: newNodeLayer.curNode.id,
name: nodeName,
info: nodeInfo
});
} else {
// 如果父节点还没有进行过异步加载,直接展开,触发其进行异步加载
zTreeObj.expandNode(newNodeLayer.curNode, true);
}
} else {
// 对于编辑操作,与 7.05 内代码相同即可,无需特殊处理
newNodeLayer.curNode.name = nodeName;
newNodeLayer.curNode.info = nodeInfo;
zTreeObj.updateNode(newNodeLayer.curNode);
}
hideForm();
}, 2000);
}
请对照 7.05 比较 submitNewNode 方法内的代码,其实改动并不大,只是需要小小的处理一下即可。