打开节点上的JSTree的渐进加载

Progressive loading of JSTree on node open

本文关键字:加载 JSTree 节点      更新时间:2023-09-26

我正在尝试使用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"]
    });
});

谢谢你的建议!

首先,您永远不会、永远不会永远不会使用async: false Ajax请求。此功能不存在。使用回调函数。

接下来,如果没有用var正确地声明JavaScript变量,就不能使用它们。忘记var会导致全局变量,这几乎总是可以被归类为bug。

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

// 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
    });
});

我已经设法用这个绑定让它做了我需要的事情:

.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]);
                }
            });

但这看起来像是一次黑客攻击,可能可以用一种更"干净"的方式做得更好。如果有人能给出更好的答案,我会很乐意重新分配正确答案和答案。谢谢