J'essaie d'écrire une fonction qui ouvre des nœuds spécifiques sur un jsTree, mais j'ai un problème lorsque la fonction est exécutée avant que mon arbre de base ne soit chargé à partir de l'appel ajax. Comment puis-je savoir si mes données jstree ont été chargées et attendre que le chargement soit terminé? Vous trouverez ci-dessous la fonction que j'essaie d'utiliser.
function openNodes(tree, nodes) {
for (i in nodes) {
$('#navigation').jstree("open_node", $(nodes[i]));
}
}
Je charge mon arbre initial avec la commande suivante
$("#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"]
});
J'ai utilisé setInterval et 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);
Le rappel ".loaded" de JStree ne fonctionne que pour les nœuds racine; "._is_loaded" peut fonctionner au lieu de vérifier la longueur du nœud, mais je ne l'ai pas essayé. Quoi qu'il en soit, les paramètres d'animation entraînent le chargement des nœuds situés plus en profondeur dans l'arborescence quelques millisecondes plus tard. La commande setInterval crée une boucle temporisée qui se ferme lorsque le ou les nœuds souhaités sont chargés.
Avant d'appeler .jstree () sur un élément, vous pouvez lier vos rappels aux événements before.jstree
et loaded.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( ... )
Dans les versions les plus récentes de jstree, vous devrez peut-être attendre que tous les nœuds aient fini de se charger avant d'interagir avec eux. Pour ce faire, vous avez besoin de:
ready.jstree
Alors:
$(selector)
.bind('ready.jstree', function(e, data) {
// invoked after jstree has loaded
})
...
Vous feriez mieux d'appeler la fonction $ .ajax () pour obtenir les données que vous voulez au début, vous pouvez appeler la fonction $ (). Jstree () dans le champ success: comme mon code.
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" ]
});
}
})
;
Vous n'êtes pas obligé d'ajouter un intervalle. Le plugin définit une classe sur le nœud qu'il charge via ajax.
.one("reselect.jstree", function (evt, data) {
if ($("#MYTREEID").find(".jstree-loading").length == 0) {
alert('my ajax tree is done loading");
}
})
[Avertissement: cela ne s'applique pas à l'OP, car le plugin d'état n'est pas répertorié dans le code d'installation.]
Si vous utilisez le plug-in d'état, utilisez l'événement state_ready.jstree à la place des événements ready.jstree ou Load.jstree.
$(selector).on('state_ready.jstree', function () {
// open desired node
}
J'utilise l'événement refresh.jstree
dans mon cas (je dois changer et actualiser dynamiquement les nœuds dans jstree très souvent).
Selon le docoment, il
déclenché à la fin d'un rafraîchissement
Exemple de code:
$.post(
[url],
...
).done(function(){
$jstree.jstree().settings.core.data = result;
$jstree.jstree().refresh();
});
$(selector).on('refresh.jstree', function(){
// do something
});