Как заставить jstree правильно работать с загруженным контентом ajax

Для проекта я пытаюсь создать древовидный элемент управления с поддержкой ajax. Мои ajax-скрипты нормально работают на серверной части, но дерево не отображается должным образом. Когда я жестко кодирую ответ ajax в своем контейнере дерева, он отображается правильно:

правильно

Однако, когда я пытаюсь загрузить дерево через ajax, я получаю следующее:

некорректный

Вот мой JS-код:

$(document).ready(function() {
    function customMenu(node) {
        var items = {
            createItem : {
                label : "Generate random number(s)",
                action: function() {
                    console.log("Creating children...");
                    var selectedId = $("#treeview").jstree("get_selected").attr("id");

                    $.ajax({
                        type: "GET",
                        contentType: "application/json; charset=utf-8",
                        url: "libs/add.php",
                        data: "fact_id=" + selectedId,
                        dataType: "json",
                        success: function(data) {
                            console.log(data);
                        }
                    });
                }
            }
        }

        return items;
    }

    $("#treeview").jstree({
        "plugins" : ["themes", "html_data", "ui", "crrm", "contextmenu"], contextmenu: {items: customMenu, select_node: true}
    });

    $.ajax({
        url: "libs/display.php",
        dataType: "json"
    }).success(function(data) {
        $("#treeview ul").append(data);
    });
});

Кто-нибудь знает, в чем моя проблема? Любая помощь будет оценена по достоинству.

РЕДАКТИРОВАТЬ Приглядевшись поближе, я понимаю, что точная проблема заключается в том, что необходимые классы не добавляются к дочерним узлам при вызове через ajax. Тем не менее, я не уверен, почему.

ДРУГОЕ ИЗМЕНЕНИЕ display.php теперь содержит следующий текст ответа:

[
    {
        "attr": {
            "id": 1
        },
        "data": 649,
            "state": "closed"
    },
    {
        "attr": {
            "id": 1
        },
       "data": 108,
       "state": "closed"
    },
    {
        "attr": {
            "id": 1
         },
        "data": 86,
        "state": "closed"
    },
    {
        "attr": {
            "id": 1
        },
        "data": 46,
        "state": "closed"
     }
]

Я иду в правильном направлении?


person Brandon M.    schedule 18.12.2013    source источник


Ответы (1)


Включена ли ваша таблица стилей и правильно ли вы установили URL-адреса для значков? Мне кажется, что именно поэтому ваши данные не стилизованы. Однако, глядя на ваш код, более вероятной причиной того, что вы не получаете свой стиль, является то, что вы просто вызываете произвольный вызов AJAX за пределами области jsTree.

Посмотрите документацию json_data подключаемого модуля для jsTree. Его легко использовать, если вы правильно настроили display.php для получения только тех узлов, которые запрашивает jsTree. Он будет совершать одновременные вызовы и получать нужные ему узлы, ваш скрипт просто должен обслуживать их:

$("#treeview").jstree({
    "plugins" : ["themes", "html_data", "ui", "crrm", "contextmenu"],
    "contextmenu": {
        items: customMenu,
        select_node: true
    },
    "json_data": {
        "ajax": {
            "url": "libs/display.php",
            "data": function(n) {
                return { id : n.attr ? n.attr("id") : 0 
            }                        
        }
    }
});

Плагин json_data в основном действует как оболочка для вызова jQuery AJAX, но события связаны непосредственно с ядром jsTree, а возвращаемые результаты обрабатываются jsTree. Вам, вероятно, потребуется немного настроить возвращаемые значения в зависимости от того, что display.php отвечает, и как вы настроили свое дерево, чтобы оно выглядело структурно.

Редактировать

Это похожее сообщение, которое может вам помочь: jsTree и AJAX › Загрузить все данные через ajax

person scrowler    schedule 18.12.2013
comment
Спасибо за ответ. Итак, в каком формате должен быть ответ от display.php? В настоящее время это всего лишь JSON-кодированная версия всего упорядоченного списка. - person Brandon M.; 18.12.2013
comment
Прямо вверху страницы документации, на которую я ссылался, есть два примера структуры данных, которые вы должны вернуть. Эти примеры относятся непосредственно к приведенному выше примеру, который я скопировал из документов, поэтому, если ваш отличается, вам нужно будет соответствующим образом настроить как приведенный выше код, так и ваш вывод display.php. - person scrowler; 18.12.2013
comment
Например, в моем приложении я возвращаю это: [{"data":{"title":"Node Title"},"attr":{"id":1,"rel":"node-type"},"state":"closed"}] - person scrowler; 18.12.2013
comment
Еще раз спасибо за вашу помощь до сих пор. Я думаю, что исправил свой скрипт display.php, но я все еще не совсем уверен, как его отобразить. Пожалуйста, смотрите мое последнее редактирование оригинального поста. - person Brandon M.; 18.12.2013
comment
Я не думаю, что вам нужно указывать детей вообще. Это работает как бы в обратном порядке: jsTree вызовет display.php и укажет идентификатор узла, для которого нужны все дочерние элементы первого уровня. Если вы укажете state: open вместо closed, он также должен будет искать дочерние узлы этих узлов. Таким образом, display.php должен принимать такой параметр, как $_GET['id'], и будет искать всех дочерних элементов этого идентификатора, а затем возвращать отформатированный результат, подобный вашему, без всех перечисленных дочерних элементов. Используйте state: open, если вы хотите также автоматически загружать дочерние узлы этих узлов. - person scrowler; 18.12.2013
comment
Чего я не понимаю, так это того, как передать идентификаторы сценарию отображения. Прошу прощения, но документации jstree сильно не хватает. - person Brandon M.; 18.12.2013
comment
Основываясь на том, что я пытаюсь сделать, не могли бы вы привести пример, который позволил бы мне использовать этот return { id : n.attr ? n.attr("id") : 0. Я понятия не имею, как использовать это утверждение. - person Brandon M.; 18.12.2013
comment
Конечно, я согласен с тем, что документы jsTree немного ниже номинала. Я предлагаю вам print_r($_GET) в display.php. Поскольку плагин json_data является оболочкой для вызова AJAX jQuery, вы можете использовать большинство тех же обратных вызовов. Добавьте success: function(msg) { console.log(msg); return msg; } после предложения data. Это должно регистрировать возврат от display.php и по-прежнему работать должным образом. Посмотрите в результатах своей консоли, и вы должны увидеть какой-то ID-ключ, который вы можете использовать в качестве родительского ID-ключа в display.php. - person scrowler; 18.12.2013
comment
Я изо всех сил стараюсь следовать вашим инструкциям, но не знаю, с чего начать. Инструкции по проекту следующие: создайте древовидный элемент управления, в котором при щелчке правой кнопкой мыши по родительскому узлу предоставляется возможность генерировать от 1 до 15 случайных чисел (в пределах указанного диапазона) в качестве дочерних узлов. Что именно должен делать код в display.php? Должен ли я возвращать идентификатор из базы данных, который соответствует идентификатору родительского узла? Должен ли я повторять объект JSON, содержащий все дочерние узлы? - person Brandon M.; 18.12.2013
comment
Я обновил свой исходный пост, чтобы показать новый ответ от display.php, когда переданный идентификатор равен 1. - person Brandon M.; 18.12.2013
comment
Изменить данные: число на данные: название: число. да, вы должны повторять объект JSON, содержащий все дочерние узлы переданного идентификатора. Эта строка возврата в Ajax либо возвращает идентификатор узла, на котором он находится, либо идентификатор ноль для узел по умолчанию (первый). Вам нужно будет изменить это на любой идентификатор вашего общего родительского корневого узла, и если у вас его нет, вам нужно будет вернуть список первых родителей, когда этот идентификатор корневого узла (в данном случае ноль) передается. - person scrowler; 18.12.2013