jsTree - 根据需要通过ajax加载子节点

时间:2011-11-10 11:05:40

标签: ajax jstree

我正在尝试让jsTree处理子节点的按需加载。我的代码是这样的:

jQuery('#introspection_tree').jstree({ 
        "json_data" : {
            "ajax" : {
                url : "http://localhost/introspection/introspection/product"
            }
    },
    "plugins" : [ "themes", "json_data", "ui" ]
    });

来自通话的json是

[
  {
    "data": "Kit 1",
    "attr": {
      "id": "1"
    },
    "children": [
      [
        {
          "data": "Hardware",
          "attr": {
            "id": "2"
          },
          "children": [

          ]
        }
      ],
      [
        {
          "data": "Software",
          "attr": {
            "id": "3"
          },
          "children": [

          ]
        }
      ]
    ]
  }
  .....
]

每个元素都可能有很多孩子,树会很大。目前这是一次加载整个树,这可能需要一些时间。当用户打开子节点时,我需要做些什么来实现按需加载?

提前致谢。

5 个答案:

答案 0 :(得分:42)

Irishka指出我正确的方向,但并没有完全解决我的问题。我摆弄着她的回答,想出了这个。仅为了清楚起见,使用两个不同的服务器功能。第一个列出了顶级的所有产品,第二个列出了给定产品的所有子项:

jQuery("#introspection_tree").jstree({
    "plugins" : ["themes", "json_data", "ui"],
    "json_data" : {
        "ajax" : {
            "type": 'GET',
            "url": function (node) {
                var nodeId = "";
                var url = ""
                if (node == -1)
                {
                    url = "http://localhost/introspection/introspection/product/";
                }
                else
                {
                    nodeId = node.attr('id');
                    url = "http://localhost/introspection/introspection/children/" + nodeId;
                }

                return url;
            },
            "success": function (new_data) {
                return new_data;
            }
        }
    }
});

从函数返回的json数据是这样的(注意每个节点中state = closed):

[
  {
    "data": "Kit 1",
    "attr": {
      "id": "1"
    },
    "state": "closed"
  },
  {
    "data": "KPCM 049",
    "attr": {
      "id": "4"
    },
    "state": "closed"
  },
  {
    "data": "Linux BSP",
    "attr": {
      "id": "8"
    },
    "state": "closed"
  }
]

不需要静态数据,树现在在每个级别都是完全动态的。

答案 1 :(得分:12)

我想默认显示第一级节点会很好,然后按需加载子项。在这种情况下,您唯一需要修改的是将"state" : "closed"添加到其子节点将按需加载的节点。

您可能希望在ajax调用中发送节点的id,以便修改代码

"json_data": {
    //root elements to be displayed by default on the first load
    "data": [
        {
            "data": 'Kit 1',
            "attr": {
                "id": 'kit1'
            },
            "state": "closed"
        },
        {
            "data": 'Another node of level 1',
            "attr": {
                "id": 'kit1'
            },
            "state": "closed"
        }
    ],
    "ajax": {
        url: "http://localhost/introspection/introspection/product",
        data: function (n) {
            return {
                "nodeid": $.trim(n.attr('id'))
            }
        }
    }
}

来自jsTree文档

注意: 如果同时设置了data和ajax,则从数据字符串呈现初始树。当打开一个关闭的节点(没有加载子节点)时,会发出一个AJAX请求。

答案 2 :(得分:10)

您需要在页面加载时将根元素设置为树数据,然后您将能够使用ajax请求检索其子元素

$("#introspection_tree").jstree({
    "plugins": ["themes", "json_data", "ui"],
    "json_data": {
        //root elements
        "data": [{"data": 'Kit 1', "attr": {"id": 'kit1'}} /*, ... */], //the 'id' can not start with a number 
        "ajax": {
            "type": 'POST',
            "data": {"action": 'getChildren'},
            "url": function (node) {
                var nodeId = node.attr('id'); //id="kit1"

                return 'yuorPathTo/GetChildrenScript/' + nodeId;
            },
            "success": function (new_data) {
                //where new_data = node children 
                //e.g.: [{'data':'Hardware','attr':{'id':'child2'}}, {'data':'Software','attr':{'id':'child3'}}]
                return new_data;
            }
        }
    }
});

有关详细信息,请参阅我对a similar question here(旧部分)的回答

答案 3 :(得分:2)

我花了几个小时来解决这个问题。最后我就是那样:

$("#resourceTree").jstree({
    "types": {
      "default": {
        "icon": "fa fa-folder-open treeFolderIcon",
      }
    },
    "plugins": ["json_data", "types", "wholerow", "search"],
    "core": {
      "multiple": false,
      "data": {
        "url" : function(node){
          var url = "rootTree.json";
          if(node.id === "specialChildSubTree")
            url = "specialChildSubTree.json";
          return url;
        },
        "data" : function(node){
          return {"id" : node.id};
        }
      }
    },
  });

rootTree.json:

[
  {
    "text": "Opened root folder",
    "state": {
      "opened": true
    },
    "children": [
      {
        "id" : "specialChildSubTree",
        "state": "closed",
        "children":true
      }
    ]
  }
]

specialChildSubTree.json:

[
  "Child 1",
  {
    "text": "Child 2",
    "children": [
      "One more"
    ]
  }
]

所以我将节点标记为带有id的ajax加载子树的父节点,我在核心配置中注意。

  

注意:   该节点必须具有"状态" :"关闭"参数,它必须有   参数" children" :是的。

我在版本3.3.3中使用jsTree.js

答案 4 :(得分:0)

以上解决方案都很好。在这里,我还提供了类似的工作解决方案,并且使用ajax调用vakata进行节点的延迟加载非常简单。当您的API像

一样工作时

https://www.jstree.com/fiddle/?lazy

并用于获取任何子节点

https://www.jstree.com/fiddle/?lazy&id=2

有关说明和完整解决方案的信息,请查看https://everyething.com/Example-of-jsTree-with-lazy-loading-and-AJAX-call

<script type="text/javascript">
        $(function () {
            $('#SimpleJSTree').jstree({
                'core' : {
                    'data' : {
                        'url' : "https://www.jstree.com/fiddle/?lazy", 
                        'data' : function (node) { 
                            return { 'id' : node.id }; 
                        } 
                    } 
                } 
            });
        });
    </script>