我有一个用jstree制作的树,当你展开节点时,它会部分加载并通过json_data插件加载。以下是代码的关键:
$("#TreeViewDiv")
.jstree(
{
json_data:
{
ajax:
{
url: "/Website/GetNodes",
data: function (node) {
//do some stuff to compile data for backend here
return {
//insert data for backend here
};
},
error: function () {
$("#TreeViewDiv").html("Error initializing tree");
}
}
},
plugins: ["json_data", "ui"]
});
然后我想扩展一些节点并选择一个叶子节点,具体取决于访问该站点的用户。我按如下方式循环执行此操作:
var nodeValues = [Parent, firstChild, leaf];
for (var j = 0; j < nodeValues .length-1; j++) {
$("#TreeViewDiv").jstree("open_node", $("input[value='" + nodeValues [j] + "']"));
}
打开Parent节点工作正常,当显示树但firstChild节点未打开时,firstChild会公开。如果我再次启动循环,则第一个子项成功打开以显示叶节点。
我的猜测是,当上述循环尝试打开请求时,请求尚未完成且firstChild树节点不存在。有没有办法在尝试打开下一个节点之前等待节点加载?谢谢!
答案 0 :(得分:2)
好的,所以我最终弄明白了。这是使用延迟执行此操作的方法。可能有一个更简洁的方式,但是在玩了一天之后我的头疼了,所以重构将不得不等待:)
var deffereds = $.Deferred(function (def) { def.resolve(); });
var nodeValues = [Parent, firstChild, leaf];
for (var j = 0; j < nodeValues .length-1; j++) {
deffereds = (function(name, deferreds) {
return deferreds.pipe(function () {
return $.Deferred(function(def) {
$("#TreeViewDiv").jstree("open_node", $("input[value='" + name + "']"), function () {
def.resolve();
});
});
});
})(nodeValues [j], deffereds);
}
这基本上将对open_node的调用放在延迟中,并使用open_node函数的回调来解析延迟,从而确保在打开父节点之前没有打开任何节点。