it-swarm.com.ru

Ленивая загрузка с jsTree

Я пытаюсь динамически загружать узлы jtree, когда они раскрываются. Небольшая документация, которую я нашел, находится в конце этой страницы .

Я нашел несколько решений, которые создают узлы один за другим с циклом вроде this . Я не пробовал, но, глядя на страницу документации, я чувствую, что jstree должен позаботиться о циклическом перемещении по узлам.

Я нашел много решений, которые используют plugins: ["json_data"], но страница документации plugins вообще не упоминает этот плагин. Это старый плагин, который больше не требуется?

Моя текущая реализация использует этот код для загрузки всего дерева за один раз:

$.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, возвращаемые сервером.

В чем дело?

15
stenci

"При использовании AJAX установите для дочерних элементов логическое значение true, а jsTree отобразит узел как закрытый и сделает дополнительный запрос для этого узла, когда пользователь откроет его.", это из jstree document и может удовлетворить ваши требования.

11
Nathan

Я дам вам, что документация/примеры довольно грубые. Я также добавлю, что источником вашей путаницы является серьезное обновление - старая версия не имеет ничего общего с новой версией, и, к сожалению, большинство примеров были написаны против этой старой версии.

Хорошая новость заключается в том, что отложенная загрузка поддерживается прямо из коробки, но это не так очевидно. Ключ в том, что он вызывает ваш data: config, когда каждый узел расширяется. Но для того, чтобы это работало, функция URL должна возвращать другой URL для данного узла. В приведенном ниже коде обратите внимание на условие возврата одного URL-адреса, если узел является корневым (#), и другого, если это не так.

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

Расширяя Натанс, отвечаем (очень минималистичным) примером: Демонстрационное дерево с отложенной загрузкой.

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, будут генерировать запрос для дочерних элементов при открытии, другие узлы обрабатываются как листья.

6
cytofu

Чтобы выполнить отложенную загрузку, вам нужен бэкэнд, который возвращает объект 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]);
                }
            }
        }
    }
});

Делая это, вы будете в состоянии лениво загрузить свое дерево.

2
André Bonna

Я сделал свою индивидуальную ленивую загрузку, комбинируя событие «select_node.jstree» и метод «create_node». При выборе каждого узла обработчик событий проверяет наличие дочерних элементов и добавляет ответ сервера на выбранный узел, узел за узлом. Мой ответ сервера не был похож или требования jstree, и эта стратегия сэкономила мне много времени и усилий . Надеюсь, это кому-нибудь поможет.

0
Alireza Ahmadi Rad