【问题标题】:Lazy loading with jsTree使用 jsTree 延迟加载
【发布时间】:2014-06-10 00:41:34
【问题描述】:

我试图在扩展 jtree 的节点时动态加载它们。我找到的小文档在this page的末尾。

我找到了一些解决方案,可以使用this one 之类的循环逐个创建节点。我没有尝试过,但是查看文档页面,我觉得 jstree 应该负责循环遍历节点。

我发现许多使用plugins: ["json_data"] 的解决方案,但plugins documentation page 根本没有提到那个插件。那是一个不再需要的旧插件吗?

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

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

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

$(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
                    };
                }
            }
        }
    });
});

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

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

[
       { "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" },
]

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

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

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

怎么了?

【问题讨论】:

    标签: jquery ajax json jstree


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      JS:

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

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

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

      【讨论】:

      • 这对我理解 JsTree 结构以及它如何与父级和延迟加载一起工作有很大帮助。你刚刚救了我我的男人:)
      • 谢谢你。这终于是我进行按需加载工作所需的示例了。
      【解决方案3】:

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

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

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

      【讨论】:

      • 从 jsTree 3.3.5 开始,您~可以~ 使用相同的 URL 并且仍然有延迟加载。下面 André Bonna 的回答显示,在 'success' 属性中设置 node.children = true 将导致 jsTree 利用延迟加载并在每次展开节点时调用相同的 URL。如果只指定一个 URL,它将是使用的 URL。
      【解决方案4】:

      要进行延迟加载,您需要一个返回 JSON 对象的后端,该对象具有具有子属性字段的树节点。 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]);
                      }
                  }
              }
          }
      });
      

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

      【讨论】:

      • 非常感谢你,拯救了我的一天!
      【解决方案5】:

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

      【讨论】:

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