0

我有一棵用 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] + "']"));
        }

打开父节点可以正常工作,并且在显示树但未打开 firstChild 节点时会暴露 firstChild。如果我再次启动循环,第一个子节点会成功打开以显示叶节点。

我的猜测是,当上述循环试图打开它时,请求尚未完成,并且 firstChild 树节点不存在。有没有办法在尝试打开下一个节点之前等待节点加载?谢谢!

4

1 回答 1

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 函数的回调来解决延迟,从而确保在打开其父节点之前没有打开任何节点。

于 2013-02-19T12:13:10.223 回答