jQuery 使用 jsTree 延迟加载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24131181/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 02:28:16  来源:igfitidea点击:

Lazy loading with jsTree

jqueryajaxjsonjstree

提问by stenci

I am trying to dynamically load the nodes of a jtree when they are expanded. The little documentation I found is at the end of this page.

我试图在扩展时动态加载 jtree 的节点。我找到的小文档在本页末尾。

I found some solutions that create the nodes one by one with a loop like this one. I have not tried it, but looking at the documentation page I have the feeling that jstree should take care of cycling through the nodes.

我找到了一些解决方案,与像一个循环创建一个节点一个这一个。我还没有尝试过,但是查看文档页面时,我觉得 jstree 应该负责在节点之间循环。

I found many solutions that use plugins: ["json_data"], but the plugins documentation pagedoesn't mention that plugin at all. Is that an old plugin that is not required anymore?

我找到了许多使用 的解决方案plugins: ["json_data"],但插件文档页面根本没有提到该插件。那是不再需要的旧插件吗?

My current implementation uses this code to load the whole tree in one shot:

我当前的实现使用此代码一次性加载整个树:

$.ajax({
    var pn = $('#project_number').val();
    url : "bomtree?part=" + pn,
    success : function(tree_content) {
        var data = $.parseJSON(tree_content);
        var config = {
            'core' : {
                'data' : data
            }
        };
        $('#bom_tree').jstree(config);
    }
});

I modified the code on the documentation page like this:

我修改了文档页面上的代码,如下所示:

$(function() {
    var pn = $('#project_number').val();
    $('#tree').jstree({
        'core' : {
            'data' : {
                'url' : function(node) {
                    return '/doc/test2';
                },
                'data' : function(node) {
                    return {
                        'part' : node.id === '#' ? pn : node.id
                    };
                }
            }
        }
    });
});

The same json text works with the first code, now with the second. The documentation says The format remains the same as the above, so I didn't change it.

相同的 json 文本适用于第一个代码,现在适用于第二个。文档说The format remains the same as the above,所以我没有改变它。

I tried also returning the same data as in the example, this:

我还尝试返回与示例中相同的数据,如下所示:

[
       { "id" : "ajson1", "parent" : "#", "text" : "Simple root node" },
       { "id" : "ajson2", "parent" : "#", "text" : "Root node 2" },
       { "id" : "ajson3", "parent" : "ajson2", "text" : "Child 1" },
       { "id" : "ajson4", "parent" : "ajson2", "text" : "Child 2" },
]

But the result is the same: jquery throws a Sizzle.error at the following line:

但结果是一样的:jquery 在以下行抛出 Sizzle.error:

Sizzle.error = function( msg ) {
    throw new Error( "Syntax error, unrecognized expression: " + msg );
};

Where the content of msgis the json data returned by the server.

其中的内容msg是服务器返回的json数据。

What's wrong?

怎么了?

回答by Nathan

"When using AJAX set children to boolean true and jsTree will render the node as closed and make an additional request for that node when the user opens it.", this is from jstreedocument and it could achieve your requirement.

“当使用 AJAX 将 children 设置为 boolean true 时,jsTree 会将节点呈现为关闭状态,并在用户打开该节点时向该节点发出额外请求。” ,这是来自jstree文档,它可以满足您的要求。

回答by cytofu

Extending Nathans answer with a (very minimalistic) example: the Demo tree with lazy loading.

使用(非常简约的)示例扩展 Nathans 的答案:延迟加载的演示树。

JS:

JS:

$('#the_tree').jstree({
    'core' : {
        'data' : {
            'url' : "tree/ajax.php", 
              'data' : function (node) {
                  return { 'id' : node.id };
              }
        }
    },

});

PHP:

PHP:

header('Content-Type: application/json');

if ( $_GET["id"] === "#" ) { 
    $data = array(
            array( "id" => "ajson1", "parent" => "#", "text" => "Simple root node"  ),
            array( "id" => "ajson2", "parent" => "#", "text" => "Root node 2", "children" => true ),

    );
}

else if ( $_GET["id"] === "ajson2" ) {
    $data = array(
        array( "id" => "ajson3", "parent" => "ajson2", "text" => "Child 1" ),
        array( "id" => "ajson4", "parent" => "ajson2", "text" => "Child 2" )
    );
}

echo json_encode( $data);

only Nodes that have "children" : true, will generate a request for children when opened, other nodes are treated as leaves.

只有具有"children" : true, 的节点在打开时才会生成对子节点的请求,其他节点被视为叶子节点。

回答by b_levitt

I'll give you that the documentation/examples is pretty rough. I'll also add that the source of your confusion comes from a major upgrade - the old versiondoesn't have much in common with the new version and unfortunately most examples were written against that old version.

我会告诉您文档/示例非常粗糙。我还要补充一点,您的困惑源于一次重大升级——旧版本与新版本没有太多共同之处,不幸的是,大多数示例都是针对旧版本编写的。

The good news is that lazy loading is supported out of the box, it just isn't that obvious. The key is that it does call your data:config as each node is expanded. But in order for it to work, the URL function must return a different URL for the given node. In the code below, note the condition to return one URL if the node is root (#), and another if it is not.

好消息是延迟加载是开箱即用的,只是没有那么明显。关键是它会data:在每个节点扩展时调用您的配置。但是为了使其工作,URL 函数必须为给定节点返回不同的 URL。在下面的代码中,注意如果节点是根 ( #)则返回一个 URL 的条件,如果不是,则返回另一个。

$('#TreeDiv')
  .jstree({
    core: {
      data: {
        url: function (node) {
          return node.id === '#' ? '/UserAccount/AccountGroupPermissions' 
                                 : '/UserAccount/AccountPermissions/' + node.id;
        },
        type: 'POST'
      }
   },
   plugins : ["checkbox"]
});

回答by André Bonna

To make a lazy loading, you need a backend that returns a JSON object with tree nodes that has children property field. Children property must contain children elements or boolean true (array or boolean). With a strongly typed language on your backend it is going to be ugly, so its best to deal with it on frontend. Example of AJAX success callback:

要进行延迟加载,您需要一个后端来返回一个 JSON 对象,该对象带有具有 children 属性字段的树节点。Children 属性必须包含子元素或布尔值 true(数组或布尔值)。在后端使用强类型语言会很丑陋,因此最好在前端处理它。AJAX 成功回调示例:

$('#tree').jstree({
    'core' : {
        'data' : {
            'url' : function(node) {
                return '/doc/test2';
            },
            'data' : function(node) {
                return {
                    'part' : node.id === '#' ? pn : node.id
                };
            },
            'success' : function(nodes) {

                var validateChildrenArray = function(node) {

                    if (!node.children || node.children.length === 0) {
                        node.children = true;
                    }
                    else {
                        for (var i = 0; i < node.children.length; i++) {
                            validateChildrenArray(node.children[i]);
                        }
                    }
                };

                for (var i = 0; i < nodes.length; i++) {
                    validateChildrenArray(nodes[i]);
                }
            }
        }
    }
});

By doing this, you are going to be able to lazy load your tree.

通过这样做,您将能够延迟加载您的树。

回答by Alireza Ahmadi Rad

I made my customized lazy loading by combining "select_node.jstree" event and "create_node" method. On selecting every node, event handler checks if there are children and adds response of server to selected node, node by node. My server response was not similar or requirements of jstree and this strategy saved me a lot of time and effort. Hope it helps somebody.

我通过结合“select_node.jstree”事件和“create_node”方法制作了我的自定义延迟加载。在选择每个节点时,事件处理程序检查是否有子节点并将服务器的响应逐个节点添加到所选节点。我的服务器响应与 jstree 不相似或要求不高,这种策略为我节省了大量时间和精力。希望它可以帮助某人。