2011-11-10 21 views
29

Estoy tratando de obtener un jsTree que funcione con la carga bajo demanda de subnodos. Mi código es la siguiente:jsTree - subnodos de carga a través de ajax bajo demanda

 
jQuery('#introspection_tree').jstree({ 
     "json_data" : { 
      "ajax" : { 
       url : "http://localhost/introspection/introspection/product" 
      } 
    }, 
    "plugins" : [ "themes", "json_data", "ui" ] 
    }); 

El JSON devuelto desde la llamada es

 
[ 
    { 
    "data": "Kit 1", 
    "attr": { 
     "id": "1" 
    }, 
    "children": [ 
     [ 
     { 
      "data": "Hardware", 
      "attr": { 
      "id": "2" 
      }, 
      "children": [ 

      ] 
     } 
     ], 
     [ 
     { 
      "data": "Software", 
      "attr": { 
      "id": "3" 
      }, 
      "children": [ 

      ] 
     } 
     ] 
    ] 
    } 
    ..... 
] 

Cada elemento puede tener un montón de hijos, el árbol va a ser grande. Actualmente esto está cargando todo el árbol a la vez, lo que podría llevar algo de tiempo. ¿Qué debo hacer para implementar la carga bajo demanda de nodos secundarios cuando los abre el usuario?

Gracias de antemano.

Respuesta

39

Irishka me indicó la dirección correcta, pero no resuelve por completo mi problema. Jugueteé con su respuesta y se me ocurrió esto. El uso de dos funciones de servidor diferentes solo se realiza para mayor claridad. La primera de ellas se enumeran todos los productos a nivel de la parte superior, la segunda listas de todos los niños de un productid dado:

jQuery("#introspection_tree").jstree({ 
    "plugins" : ["themes", "json_data", "ui"], 
    "json_data" : { 
     "ajax" : { 
      "type": 'GET', 
      "url": function (node) { 
       var nodeId = ""; 
       var url = "" 
       if (node == -1) 
       { 
        url = "http://localhost/introspection/introspection/product/"; 
       } 
       else 
       { 
        nodeId = node.attr('id'); 
        url = "http://localhost/introspection/introspection/children/" + nodeId; 
       } 

       return url; 
      }, 
      "success": function (new_data) { 
       return new_data; 
      } 
     } 
    } 
}); 

El JSON datos devueltos por las funciones es como este (nótese el estado = cerrado en cada nodo):

 
[ 
    { 
    "data": "Kit 1", 
    "attr": { 
     "id": "1" 
    }, 
    "state": "closed" 
    }, 
    { 
    "data": "KPCM 049", 
    "attr": { 
     "id": "4" 
    }, 
    "state": "closed" 
    }, 
    { 
    "data": "Linux BSP", 
    "attr": { 
     "id": "8" 
    }, 
    "state": "closed" 
    } 
] 

No se necesitan datos estáticos, el árbol ahora es completamente dinámico en cada nivel.

+6

¡Muchas gracias! Perdí demasiado tiempo tratando de resolver esto. No estaba tan claro en la documentación. –

+13

documentación es una mierda ... al menos para comenzar con jstree – bbqchickenrobot

+2

Muchas gracias. La estructura de datos de retorno en particular me ayudó, ya que estaba trabajando bajo la falsa suposición de que el JSON devuelto debería ser un objeto con hijos como una matriz, no la matriz en sí misma. – arvidkahl

9

debe configurar elementos raíz como datos de árboles sobre carga de la página y luego usted será capaz de recuperar a sus hijos con una petición AJAX

$("#introspection_tree").jstree({ 
    "plugins": ["themes", "json_data", "ui"], 
    "json_data": { 
     //root elements 
     "data": [{"data": 'Kit 1', "attr": {"id": 'kit1'}} /*, ... */], //the 'id' can not start with a number 
     "ajax": { 
      "type": 'POST', 
      "data": {"action": 'getChildren'}, 
      "url": function (node) { 
       var nodeId = node.attr('id'); //id="kit1" 

       return 'yuorPathTo/GetChildrenScript/' + nodeId; 
      }, 
      "success": function (new_data) { 
       //where new_data = node children 
       //e.g.: [{'data':'Hardware','attr':{'id':'child2'}}, {'data':'Software','attr':{'id':'child3'}}] 
       return new_data; 
      } 
     } 
    } 
}); 

Véase mi respuesta a a similar question here (la parte antigua) para más detalles

+0

¿Cuál es la razón de Identificación del que no empiezan con un número? –

+2

Sintaxis Atributo Valor Valores \t Descripción Identificación \t Especifica un identificador único para un elemento. Reglas de nombres: Debe comenzar con una letra AZ o az Puede ir seguido de: letras (A-Za-z), dígitos (0-9), guiones ("-") y guiones bajos ("_") En HTML, todos los valores no distinguen entre mayúsculas y minúsculas ver aquí [http://www.w3schools.com/tags/att_standard_id.asp] – Irishka

+0

Gracias, no tenía eso en mente. –

12

Supongo que sería bueno mostrar por defecto nodos de primer nivel y luego los niños se cargarán bajo demanda. En ese caso, lo único que tiene que modificar es agregar "state" : "closed" a los nodos cuyos nodos secundarios se cargarán bajo demanda.

Es posible que desee enviar el id del nodo de llamada AJAX para que modifique su código

"json_data": { 
    //root elements to be displayed by default on the first load 
    "data": [ 
     { 
      "data": 'Kit 1', 
      "attr": { 
       "id": 'kit1' 
      }, 
      "state": "closed" 
     }, 
     { 
      "data": 'Another node of level 1', 
      "attr": { 
       "id": 'kit1' 
      }, 
      "state": "closed" 
     } 
    ], 
    "ajax": { 
     url: "http://localhost/introspection/introspection/product", 
     data: function (n) { 
      return { 
       "nodeid": $.trim(n.attr('id')) 
      } 
     } 
    } 
} 

De jsTree documentación

NOTA: Si se establecen tanto los datos como el Ajax el árbol inicial se representan a partir de la cadena de datos. Al abrir un nodo cerrado (que no tiene hijos cargados) se realiza una solicitud de AJAX.

1

Pasé horas en este problema. Finalmente lo tengo de esa manera:

$("#resourceTree").jstree({ 
    "types": { 
     "default": { 
     "icon": "fa fa-folder-open treeFolderIcon", 
     } 
    }, 
    "plugins": ["json_data", "types", "wholerow", "search"], 
    "core": { 
     "multiple": false, 
     "data": { 
     "url" : function(node){ 
      var url = "rootTree.json"; 
      if(node.id === "specialChildSubTree") 
      url = "specialChildSubTree.json"; 
      return url; 
     }, 
     "data" : function(node){ 
      return {"id" : node.id}; 
     } 
     } 
    }, 
    }); 

rootTree.json:

[ 
    { 
    "text": "Opened root folder", 
    "state": { 
     "opened": true 
    }, 
    "children": [ 
     { 
     "id" : "specialChildSubTree", 
     "state": "closed", 
     "children":true 
     } 
    ] 
    } 
] 

specialChildSubTree.json:

[ 
    "Child 1", 
    { 
    "text": "Child 2", 
    "children": [ 
     "One more" 
    ] 
    } 
] 

Así que marcan el nodo que se convierta en el padre del ajax cargado subárbol con una identificación, observo en la configuración central.

NOTA: el nodo debe tener el "estado": "cerrado" parámetro y debe tener los parámetros "niños": true.

estoy usando jsTree.js en la versión 3.3.3

Cuestiones relacionadas