Ответ 1
"При использовании AJAX установите для детей значение boolean true, а jsTree сделает node закрытым и сделает дополнительный запрос для этого node, когда пользователь откроет его.. Это от jstree, и он может достичь ваших требований.
Я пытаюсь динамически загружать узлы jtree при их расширении. Маленькая документация, которую я нашел, находится в конце этой страницы.
Я нашел несколько решений, которые создают узлы один за другим с помощью цикла, такого как этот. Я не пробовал, но глядя на страницу документации, я чувствую, что jstree должен заботиться о циклическом перемещении по узлам.
Я нашел много решений, которые используют plugins: ["json_data"]
, но страница документации плагинов не упоминает этот плагин вообще. Это старый плагин, который больше не требуется?
Моя текущая реализация использует этот код для загрузки всего дерева за один снимок:
$.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, возвращаемые сервером.
Что не так?
"При использовании AJAX установите для детей значение boolean true, а jsTree сделает node закрытым и сделает дополнительный запрос для этого node, когда пользователь откроет его.. Это от jstree, и он может достичь ваших требований.
Я дам вам, что документация/примеры довольно грубые. Я также добавлю, что источник вашей путаницы исходит из серьезного обновления - старая версия не имеет много общего с новой версией и, к сожалению, большинство примеров были написаны против этой старой версии.
Хорошей новостью является то, что ленивая загрузка поддерживается из коробки, это просто не так очевидно. Ключ в том, что он вызывает ваш конфигуратор data:
, поскольку каждый node расширяется. Но для того, чтобы он работал, функция URL должна возвращать другой URL для данного node. В приведенном ниже коде обратите внимание на условие возврата одного URL-адреса, если node является корневым (#
), а другой, если это не так.
$('#TreeDiv')
.jstree({
core: {
data: {
url: function (node) {
return node.id === '#' ? '/UserAccount/AccountGroupPermissions'
: '/UserAccount/AccountPermissions/' + node.id;
},
type: 'POST'
}
},
plugins : ["checkbox"]
});
Расширение ответа 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
, генерируют запрос для детей при открытии, другие узлы обрабатываются как листья.
Чтобы сделать ленивую загрузку, вам нужен бэкэнд, который возвращает объект JSON с узлами дерева, у которого есть дочернее свойство. Детское свойство должно содержать дочерние элементы или логические истинные (массивы или булевы). С сильно типизированным языком на вашем бэкэнде это будет уродливо, поэтому лучше всего справиться с ним на фронте. Пример обратного вызова успеха 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]);
}
}
}
}
});
Сделав это, вы сможете ленить загружать свое дерево.
Я сделал свою настроенную ленивую загрузку, объединив событие "select_node.jstree" и метод "create_node". При выборе каждого node обработчик событий проверяет наличие дочерних элементов и добавляет ответ сервера на выбранные node, node на node. Ответ моего сервера не был похож или на требования jstree, и эта стратегия сэкономила мне много времени и сил. Надеюсь, это поможет кому-то.