2011-03-23 9 views
9

Me gustaría saber cómo actualizar dinámicamente los datos del componente dojo.dijit.tree. En este momento estoy creando el árbol usando dojo.data.ItemFileReadStore y dijit.tree.ForestStoreModel. Una vez que creo el árbol, me gustaría volver a cargarlo periódicamente con nuevos datos JSON.Cómo actualizar los datos del árbol dojo dinámicamente

Éste es cómo crear el árbol en la actualidad

<div dojoType="dojo.data.ItemFileReadStore" jsId="myStore" url=getJSONResult></div> 

<div dojoType="dijit.tree.ForestStoreModel" jsId="myModel" store="myStore" query="{type:'cat'}" rootId="myRoot" rootLabel="Data" childrenAttrs="children"></div> 

<div dojoType="dijit.Tree" model="myModel" labelAttr="sname" label="Data" /> 

Gracias de antemano.

Respuesta

20

Explícitamente usted "no puede", pero eso no significa que no pueda cortar cosas en pedazos y morir en el intento.

refreshTree : function(){ 
    dijit.byId("myTree").dndController.selectNone(); // As per the answer below  
    // Credit to this discussion: http://mail.dojotoolkit.org/pipermail/dojo-interest/2010-April/045180.html 
    // Close the store (So that the store will do a new fetch()). 
    dijit.byId("myTree").model.store.clearOnClose = true; 
    dijit.byId("myTree").model.store.close(); 

    // Completely delete every node from the dijit.Tree  
    dijit.byId("myTree")._itemNodesMap = {}; 
    dijit.byId("myTree").rootNode.state = "UNCHECKED"; 
    dijit.byId("myTree").model.root.children = null; 

    // Destroy the widget 
    dijit.byId("myTree").rootNode.destroyRecursive(); 

    // Recreate the model, (with the model again) 
    dijit.byId("myTree").model.constructor(dijit.byId("myTree").model) 

    // Rebuild the tree 
    dijit.byId("myTree").postMixInProperties(); 
    dijit.byId("myTree")._load(); 

}, 

Esto actualizará su árbol.

+1

Gracias por su respuesta Laykes. Su secuencia de comandos, de hecho, actualiza la representación del árbol. Sin embargo, con este ejemplo no he podido cargar nuevos datos en él. Implementé una actualización periódica llamando a la función que creó. Mi tienda tiene la propiedad url configurada en un nombre de archivo que contiene datos JSON. Estoy cambiando los datos en el archivo, pero el árbol siempre muestra los datos iniciales. ¿Sabes cómo cargar nuevos datos en él? – Zion

+0

Lo siento TheLostGuy, supuse que su tienda está configurada para actualizar al cerrar. Agregue esto: dijit.byId ("myTree"). Model.store.clearOnClose = true; – Layke

+0

Muchas gracias Laykes. Esto de hecho está trabajando para mí ahora. ¡Salud! – Zion

-1

No admitido actualmente. Ver here.

+0

Gracias por su respuesta Andy. ¿Conoces un árbol alternativo que se puede actualizar de forma dinámica? – Zion

+0

No en Dojo, pero otros kits de herramientas pueden ofrecer esto. Lo que hago en Dojo es poner un widget dojox.widget.Standby sobre todo el árbol (cargar ícono giratorio) y simplemente destruir el árbol y vincular un nuevo árbol a una nueva tienda (o tienda repoblada). – Andy

9

Aquí hay un problema con la solución de Layke (que de lo contrario funciona) encontrada en pruebas de preproducción para un sitio web comercial.

Caso 1:

  • Crear & pueblan un árbol.
  • Haga clic en un nodo para seleccionar.
  • Ejecute refreshTree como en la solución de Layke.
  • Haga clic en un nodo, obtenga el error "this.labelNode is undefined".

Ahora empezar de nuevo, el caso 2:

  • Crear & pueblan un árbol.
  • Haga clic en un nodo para seleccionar.
  • Ctrl-clic en el nodo seleccionado previamente.
  • Ejecute refreshTree como en la solución de Layke.
  • Haga clic en un nodo, sin error.

Las referencias de selección almacenados en la primera selección se utilizan para deshacer los atributos de selección (color de fondo, etc.) cuando se realiza la segunda selección. Desafortunadamente, los objetos referidos están ahora en el cubo de bits. El código modificado parece estar listo para producción, es decir, no ha fallado ninguna prueba previa a la producción.

La solución es poner:

Tree.dndController.selectNone(); 

antes de la primera línea de solución refreshTree de Layke anteriormente.

En respuesta a las sugerencias del meta, aquí está:

refreshTree : function() { 
    // Destruct the references to any selected nodes so that 
    // the refreshed tree will not attempt to unselect destructed nodes 
    // when a new selection is made. 
    // These references are contained in Tree.selectedItem, 
    // Tree.selectedItems, Tree.selectedNode, and Tree.selectedNodes. 
    Tree.dndController.selectNone(); 

    Tree.model.store.clearOnClose = true; 
    Tree.model.store.close(); 

    // Completely delete every node from the dijit.Tree  
    Tree._itemNodesMap = {}; 
    Tree.rootNode.state = "UNCHECKED"; 
    Tree.model.root.children = null; 

    // Destroy the widget 
    Tree.rootNode.destroyRecursive(); 

    // Recreate the model, (with the model again) 
    Tree.model.constructor(dijit.byId("myTree").model) 

    // Rebuild the tree 
    Tree.postMixInProperties(); 
    Tree._load(); 

} 
1

Gracias por esta función, funciona muy bien en mi árbol.

Un aviso para los que son nuevos en dojo (como yo) ...Después de la creación del árbol, que se necesita para extender el árbol con la función de actualización:

dojo.extend(dijit.Tree, { 
    refresh: function() { 
     this.dndController.selectNone(); 
     //... 
    } 
}); 

A continuación, puede llamar a la función con:

dijit.byId('myTree').refresh(); 
0

actualización de su tienda se actualizará automáticamente su árbol!

  1. Necesita un FileWriteStore, que le da la posibilidad de modificar sus datos.
  2. Utilice la tienda para buscar los artículos que desea actualizar mediante consulta.
  3. Actualiza cada artículo devuelto.
  4. Luego guarde la tienda y el árbol se actualizará.

    FileWriteStore.fetch({ 
        query: { color: "red" }, 
        onComplete: function(items){ 
         for (var i = 0; i < items.length; i++){ 
          FileWriteStore.setValue(items[i], "color", "green"); 
         } 
         FileWriteStore.save();    
        } 
    }); 
    
0

solución de Layke no funcionó para mí. Estoy usando dojo 1.9.1. Mi tienda es del tipo "ItemFileWriteStore" y el modelo de tipo "TreeStoreModel".

myStore = new ItemFileWriteStore({ 
    url : "../jaxrs/group/tree" 
}); 

itemModel = new TreeStoreModel({ 
    store : myStore, 
    query : { 
     id : "0" 
    } 
}); 
parser.parse(); 

Esto funciona para mí:

var tree = dijit.byId('myTree'); 
tree.dndController.selectNone(); 
tree._itemNodesMap = {}; 
tree.model.root = null; 
tree.model.store.clearOnClose = true; 
tree.model.store.urlPreventCache = true; 
tree.model.store.revert(); 
tree.model.store.close(); 
tree.rootNode.state = "UNCHECKED"; 
if (tree.rootNode) { 
    tree.rootNode.destroyRecursive(); 
} 
tree.postMixInProperties(); 
tree._load(); 
0

Al ir a través de estas respuestas que he construido mi propio método para actualizar los nodos específicos una vez en un momento y no necesita la actualización.

_refreshNodeMapping: function (newNodeData) { 

    if(!this._itemNodesMap[newNodeData.identity]) return; 

    var nodeMapToRefresh = this._itemNodesMap[newNodeData.identity][0].item; 
    var domNode = this._itemNodesMap[newNodeData.identity][0].domNode; 

    //For every updated value, reset the old ones 
    for(var val in newNodeData) 
    { 
     nodeMapToRefresh[val] = newNodeData[val]; 

     if(val == 'label') 
     { 
      domNode.innerHTML = newNodeData[val]; 
     } 
    } 
} 
Cuestiones relacionadas