【问题标题】:Progressive loading of JSTree on node open在节点打开时渐进式加载 JSTree
【发布时间】:2013-12-17 11:17:56
【问题描述】:

我正在尝试使用JSTree 逐步加载节点树 - 目前我有一个根节点,它基于一些路径,其中包含完整数据和子节点及其名称和路径。当用户打开节点时,我需要更改其中的数据(加载完整数据)。这意味着我的 JSON 起初看起来像这样:

{
"data":"Parent",
"attr":{"id:":"103.510.1.4556314","name:":"Parent"},
"children":[{
    "data":"Child_1",
    "attr":{"name":"Child_1","path":"/my/path/Child1"},
    "children":[]
        },
        "data":"Child_2",
    "attr":{"name":"Child_2","path":"/my/path/Child2"},
    "children":[]
        }]
} 

在打开 Child_2 后,应再次从源中为该节点加载完整数据。之后它应该看起来像这样:

{
"data":"Parent",
"attr":{"id:":"103.510.1.4556314","name:":"Parent"},
"children":[{
    "data":"Child_1",
    "attr":{"name":"Child_1","path":"/my/path/Child1"},
    "children":[]
        },
        "data":"Child_2",
    "attr":{"name":"Child_2","id":"103.510.1.4523317"},
    "children":[{
        "data":"GrandChild_1",
        "attr":{"name":"Child_1","path":"/my/path/Child2/GrandChild1"},
            "children":[]
            },
            "data":"GrandChild_2",
        "attr":{"name":"Child_2","path":"/my/path/Child2/GrandChild2"},
        "children":[]
            }]
        }]
}

请问我该如何实现这个功能?

这是我的 Ajax 调用:

function getJSONData(key) {

    var test;
    $.ajax({
        async: false,
        type: "GET",
        url: "/services/jstree?key=" + key,
        dataType: "json",

        success: function (json) {
            test = json;
        },

        error: function (xhr, ajaxOptions, thrownError) {
            alert(xhr.status);
            alert(thrownError);
            test = "error";
        }
    });
    return test;
}

在创建树时使用:

$(".tree-search").click(function () {
    var jsonData = getJSONData($(this).attr("path"));
    treeContainer = $(this).siblings('.tree-container');
    treeContent = treeContainer.children('.tree-content');
    treeContent.jstree({
        "json_data": {"data": jsonData},
        "plugins": ["themes", "json_data", "ui", "checkbox"]
    });
});

感谢您的建议!

【问题讨论】:

  • 您可能想要设置一个 jsFiddle,包含您当前拥有的 HTML 和模型 Ajax 请求。
  • @Tomalak 我几乎拥有实现我想要的所需的代码,所以我可能会跳过它并很快发布答案。不过感谢您的关注!
  • 我有一些相关的评论,但并不构成完整的答案(因为如果不查看更多代码,这是不可能的)。反正。见下文。

标签: javascript jquery ajax jstree


【解决方案1】:

首先,你永远,永远永远使用async: false Ajax 请求。该功能不存在。使用回调函数。

接下来,您不能使用 JavaScript 变量,除非用 var 正确声明它们。忘记var 会导致全局变量,这几乎总是可以归类为错误。

第三,您可能需要事件委托,因为您的子树元素是动态创建的,并且仍然应该对相同的事件做出反应。

// read jQuery docs on Deferred to find out about fail() and done() etc.
function getJSONData(key) {
    return $.get("/services/jstree", {key: key})
        .fail(function (xhr, ajaxOptions, thrownError) {
            alert(xhr.status + "\n" + thrownError);
        });
    });
}

// delegate "click" event handling to the document
$(document).on("click", ".tree-search", function () {
    var key = $(this).attr("path");

    getJSONData(key).done(function (jsonData) {
        // call jstree() with jsonData
    });
});

【讨论】:

  • 感谢您提供的建议,我觉得它非常有用。然而,孩子加载的代码不是我需要的,但可能是我没有足够清楚地说明我的问题。谢谢!
【解决方案2】:

我已经设法通过这个绑定完成了我需要的工作:

.bind("open_node.jstree", function (event, data) {
                children = data.inst._get_children(data.rslt.obj);
                for(var i=0; i<children.length; i++){
                    data.inst.create_node(data.rslt.obj, "inside", getJSONData(children[i].getAttribute('path')));
                    data.inst.delete_node(children[i]);
                }
            });

但它看起来像一个 hack,可能可以以更“干净”的方式做得更好。如果有人提出更好的答案,我很乐意重新分配正确的答案。谢谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多