【问题标题】:How can I tell if jsTree has fully loaded?如何判断 jsTree 是否已满载?
【发布时间】:2012-07-12 12:48:31
【问题描述】:

我正在尝试编写一个在 jsTree 上打开特定节点的函数,但我遇到了一个问题,即在从 ajax 调用加载我的基树之前执行该函数。如何判断我的 jstree 数据是否已加载并等待加载完成。以下是我尝试使用的功能。

function openNodes(tree, nodes) {
    for (i in nodes) {
        $('#navigation').jstree("open_node", $(nodes[i]));
    }
}

我正在使用以下命令加载我的初始树

$("#navigation").jstree({
    "json_data": {
        "ajax": {
            "url": function(node) {
                var url;
                if (node == -1) {
                    url = "@Url.Action("BaseTreeItems", "Part")";
                } else {
                    url = node.attr('ajax');
                }
                return url;
            },
            "dataType": "text json",
            "contentType": "application/json charset=utf-8",
            "data": function(n) { return { id: n.attr ? n.attr("id") : 0, ajax: n.attr ? n.attr("ajax") : 0 }; },
            "success": function() {
            }
        }
    },
    "themes": { "theme": "classic" },
    "plugins": ["themes", "json_data", "ui"]
});

【问题讨论】:

  • 你设置jsTree数据类型为json,通过ajax加载。要加载 jsTree,首先需要加载数据。您可以做的是在打开节点时触发数据加载。它能解决你的问题吗?

标签: javascript jstree


【解决方案1】:

在对元素调用 .jstree() 之前,可以将回调绑定到 before.jstreeloaded.jstree 事件:

$(selector)
.bind('before.jstree', function(e, data) {
    // invoked before jstree starts loading
})
.bind('loaded.jstree', function(e, data) {
    // invoked after jstree has loaded
    $(this).jstree("open_node", $(nodes[i]));
})
.jstree( ... )

【讨论】:

  • 这会将 .jstree(....) 推迟到 jstree 加载之后还是初始 ajax 数据加载之后?
  • 无论如何它都不会推迟 .jstree() 。这里只涉及到几个事件。当 jstree 在特定时刻触发它们的相应事件时,将调用这些回调。
  • 我真的很想推迟 .jstree("open_node", $(nodes[i]));直到加载 ajax 数据之后。
  • 你需要把 .jstree("open_node", $(nodes[i]));在加载的回调函数中。我已经为你更新了答案。
  • @craftsman 嗨,我使用的是旧的 jstree v 1.0,并且使用的绑定 'loaded.jstree' 事件的顺序与上述不完全相同,但如下所示: $("#selector") 。 jstree({ theme: { // 这里声明的主题}, plugins: ["themes", "html_data", "ui"], core: {} }).bind("loaded.jstree", function (event, data) { alert('称为加载的 jstree ');// 之后要执行的语句});但是 alert();不叫。知道为什么吗?我想绑定必须在调用选择器上的 jstree 之前发生。(?)
【解决方案2】:

在较新版本的 jstree 中,您可能需要等到所有节点都完成加载后才能与它们交互。为此,您需要:

ready.jstree

所以:

$(selector)
    .bind('ready.jstree', function(e, data) {
        // invoked after jstree has loaded
     })
...

【讨论】:

    【解决方案3】:

    我使用了 setInterval 和 clearInterval:

    var interval_id = setInterval(function(){
         // $("li#"+id).length will be zero until the node is loaded
         if($("li#"+id).length != 0){
             // "exit" the interval loop with clearInterval command
             clearInterval(interval_id)
             // since the node is loaded, now we can open it without an error
             $("#tree").jstree("open_node", $("li#"+id))
          }
    }, 5);
    

    JStree 的“.loaded”回调只对根节点有效; “._is_loaded”可能会起作用,而不是检查节点的长度,但我还没有尝试过。无论哪种方式,动画设置都会导致树中较深的节点在几毫秒后加载。 setInterval 命令会创建一个定时循环,在加载所需节点时退出。

    【讨论】:

    • 我面临与 OP 相同的问题,但我无法让您的解决方案发挥作用。如果所有节点最初都是关闭的,则无法使用 $("li#"+id) 选择器找到关闭节点下的任何子节点,因为它们尚不存在于 DOM 中(通过在调试模式下扩展元素来检查 DOM 不会'关闭时在父 DOM 下找不到任何额外的 li 项)。有什么想法/想法吗?
    【解决方案4】:

    你最好先调用$.ajax()函数来获取你想要的数据,你可以在success:字段中调用$().jstree()函数,就像我的代码一样。

        var fullTree;
    $.ajax({
      url :"./php/select_tree.php",
      data : fullTree,
      method : "GET",
      dataType : "json",
      success : function(fullTree){
        $("#jstree").jstree({
          "core" : {
            "data" :fullTree,
            "check_callback" : true
           },
           "plugins" : [ "contextmenu", "dnd", "changed", "wholerow" ]
        });
      }
    })
    ;
    

    【讨论】:

      【解决方案5】:

      在我的情况下我使用refresh.jstree事件(我需要经常动态更改和刷新jstree中的节点)。

      根据文档,它

      刷新调用完成时触发

      jsTree Doc (Events)

      示例代码:

      $.post( [url], ... ).done(function(){ $jstree.jstree().settings.core.data = result; $jstree.jstree().refresh(); }); $(selector).on('refresh.jstree', function(){ // do something });

      【讨论】:

        【解决方案6】:

        [免责声明:这不适用于 OP,因为状态插件未在设置代码中列出。]

        如果您使用状态插件,请使用 state_ready.jstree 事件而不是 ready.jstree 或 loaded.jstree 事件。

        $(selector).on('state_ready.jstree', function () {
            // open desired node
        })
        

        【讨论】:

          【解决方案7】:

          您不必添加间隔。该插件在通过 ajax 加载的节点上设置一个类。

          .one("reselect.jstree", function (evt, data) {
                  if ($("#MYTREEID").find(".jstree-loading").length == 0) {
                      alert('my ajax tree is done loading");
                  }
              })
          

          【讨论】:

            【解决方案8】:

            由于我没有找到解决方案,这适用于当前版本的 JSTree (3.3.7) 我将在这里发布我的工作方法。

            首先,我在 select_node 上绑定并告诉 jstree 打开父节点,每当我选择 i 节点时。

            var strIdentifierJsTree  = "#your-whatever-id-to-jstree";
            var strNode2Select = "#your-whatever-id-to-your-node-which-parents-has-to-be-showed";
            
            $( strIdentifierJsTree ).on("select_node.jstree", function (e, data) {
                   $(strIdentifierJsTree).jstree(true).open_node( data.node.parent );
            });
            

            然后我绑定到 load-Function:

            $( strIdentifierJsTree ).bind('loaded.jstree', function(e, data) {
                   $(strIdentifierJsTree).jstree(true).select_node( strNode2Select );
            });
            

            现在它将在 JSTree 初始化后(完全加载时)选择我的节点,并打开所有父节点,无论嵌套深度如何。像其他答案中提到的那样,单个开放节点方法对我不起作用。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-11-11
              • 2010-12-20
              • 2012-07-11
              • 2012-05-19
              • 1970-01-01
              • 2020-09-21
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多