当前位置 : 主页 > 网页制作 > Dojo >

How to update dojo tree data dynamically

来源:互联网 收集:自由互联 发布时间:2021-06-15
7 down vote favorite 6 I would like to know how ot update the data of the dojo.dijit.tree component dynamically. At the moment I'm creating the tree using dojo.data.ItemFileReadStore and dijit.tree.ForestStoreModel. Once I create the tree,


7 down vote favorite 6

I would like to know how ot update the data of the dojo.dijit.tree component dynamically. At the moment I'm creating the tree using dojo.data.ItemFileReadStore and dijit.tree.ForestStoreModel. Once I create the tree, I would like to reload it periodically with new JSON data.

This is how I create the tree at the moment:

<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" />

Thanks in advance.

javascript  dojo  tree share | improve this question edited Feb 10 '12 at 15:08 BoltClock
264k 55 638 825 asked  Mar 23 '11 at 17:16 Zion
75 2 3 9   add a comment

7 Answers

active oldest votes up vote 17 down vote accepted

Explicitly you "can't", but that doesn't mean you can't hack things to pieces and die trying.

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(); },

This will refresh your Tree.

share | improve this answer edited Jan 11 '13 at 13:03
answered  Mar 25 '11 at 9:25 Layke
11.6k 4 41 72   1   Thanks for your answer Laykes. Your script does indeed refresh the tree rendering. However, with this example I haven't been able to load new data on it. I have implemented a periodic refresh calling the function that you created. My store has the url property set to a filename which contains JSON data. I'm changing the data on the file but the tree is always rendering the initial data. Do you know how to load new data on it? –   Zion  Mar 25 '11 at 13:10   Sorry TheLostGuy, I assumed that your store is set to refresh on close. Add this: dijit.byId("myTree").model.store.clearOnClose = true; –   Layke  Mar 25 '11 at 15:53   Thanks a lot Laykes. This is indeed working for me now. Cheers! –   Zion  Apr 1 '11 at 12:38   Wish I could give more upvotes for this answer. You saved my hide! –   JoeCortopassi  May 19 '11 at 16:37 add a comment up vote 9 down vote

Here's a problem with Layke's solution (which otherwise does work) found by pre-production testing for a commercial website.

Case 1:

  • Create & populate a tree.
  • Click on a node to select.
  • Execute refreshTree as in Layke's solution.
  • Click on a node, get error "this.labelNode is undefined".

Now start again, case 2:

  • Create & populate a tree.
  • Click on a node to select.
  • Ctrl-click on the previously selected node.
  • Execute refreshTree as in Layke's solution.
  • Click on a node, no error.

The stored selection references to the first selection are being used to undo the selection attributes (background color, etc.) when the second selection is made. Unfortunately, the referred-to objects are now in the bit-bucket. The modified code appears to be production-ready, i.e. hasn't failed any pre-production tests.

The solution is to put:

Tree.dndController.selectNone();

prior to first line of Layke's refreshTree solution above.

In response to meta suggestions, here it is:

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(); }
share | improve this answer edited Feb 10 '12 at 16:34
answered  Feb 9 '12 at 23:35 kcrossen
111 1 4   add a comment up vote 1 down vote

Thanks for this function, works great in my tree.

A notice to those who are new to dojo (like me)... After creation of the tree, it is needed to extend the tree with the refresh function:

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

Then you can call the function with:

dijit.byId('myTree').refresh();
share | improve this answer answered  Feb 23 '12 at 16:18 Taneeda
11 2   add a comment up vote 0 down vote

Updating your store will automatically update your tree!

  1. You need a FileWriteStore, which gives you the ability to modify your data.
  2. Use the store to fetch the items you want to update via query.
  3. Update each item returned.
  4. Then save the store and the tree will update.

    FileWriteStore.fetch({ query: { color: "red" }, onComplete: function(items){ for (var i = 0; i < items.length; i++){ FileWriteStore.setValue(items[i], "color", "green"); } FileWriteStore.save(); } });
share | improve this answer answered  Oct 10 '13 at 22:31 Tigertron
39 3   add a comment up vote 0 down vote

Layke's solution did not work for me. I am using dojo 1.9.1. My store is of type "ItemFileWriteStore" and the model of type "TreeStoreModel".

myStore = new ItemFileWriteStore({ url : "../jaxrs/group/tree" }); itemModel = new TreeStoreModel({ store : myStore, query : { id : "0" } }); parser.parse();

This works for me:

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();
share | improve this answer answered  Nov 20 '13 at 15:58 Markus Kühn
1   add a comment up vote 0 down vote

While going through these answers I've built my own method to update specific nodes once at a time and NOT need the refresh.

_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]; } } }
share | improve this answer answered  Sep 8 at 17:50 Alex Boisselle
1 1   add a comment up vote -1 down vote

Not supported at present. See here.

share | improve this answer edited Apr 16 '13 at 18:59 prongs
2,365 6 33 68 answered  Mar 23 '11 at 17:32 Andy
379 3 6     Thanks for your response Andy. Do you know an alternative tree which can be updated dynamically? –   Zion Mar 24 '11 at 17:37    Not in Dojo - but other toolkits may offer this. What I do in Dojo is put up a dojox.widget.Standby widget over the entire tree (loading icon spinner) and simply destroy the tree and bind a new tree to a new store (or repopulated store). –   Andy  Mar 25 '11 at 14:30   While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. –   ThinkingStiff Nov 14 '12 at 19:17



http://stackoverflow.com/questions/5409097/how-to-update-dojo-tree-data-dynamically

7 down vote favorite 6

I would like to know how ot update the data of the dojo.dijit.tree component dynamically. At the moment I'm creating the tree using dojo.data.ItemFileReadStore and dijit.tree.ForestStoreModel. Once I create the tree, I would like to reload it periodically with new JSON data.

This is how I create the tree at the moment:

<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" />

Thanks in advance.

javascript  dojo  tree share | improve this question edited Feb 10 '12 at 15:08 BoltClock
264k 55 638 825 asked  Mar 23 '11 at 17:16 Zion
75 2 3 9   add a comment

7 Answers

active oldest votes up vote 17 down vote accepted

Explicitly you "can't", but that doesn't mean you can't hack things to pieces and die trying.

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(); },

This will refresh your Tree.

share | improve this answer edited Jan 11 '13 at 13:03
answered  Mar 25 '11 at 9:25 Layke
11.6k 4 41 72   1   Thanks for your answer Laykes. Your script does indeed refresh the tree rendering. However, with this example I haven't been able to load new data on it. I have implemented a periodic refresh calling the function that you created. My store has the url property set to a filename which contains JSON data. I'm changing the data on the file but the tree is always rendering the initial data. Do you know how to load new data on it? –   Zion  Mar 25 '11 at 13:10      Sorry TheLostGuy, I assumed that your store is set to refresh on close. Add this: dijit.byId("myTree").model.store.clearOnClose = true; –   Layke  Mar 25 '11 at 15:53      Thanks a lot Laykes. This is indeed working for me now. Cheers! –   Zion  Apr 1 '11 at 12:38      Wish I could give more upvotes for this answer. You saved my hide! –   JoeCortopassi  May 19 '11 at 16:37 add a comment up vote 9 down vote

Here's a problem with Layke's solution (which otherwise does work) found by pre-production testing for a commercial website.

Case 1:

  • Create & populate a tree.
  • Click on a node to select.
  • Execute refreshTree as in Layke's solution.
  • Click on a node, get error "this.labelNode is undefined".

Now start again, case 2:

  • Create & populate a tree.
  • Click on a node to select.
  • Ctrl-click on the previously selected node.
  • Execute refreshTree as in Layke's solution.
  • Click on a node, no error.

The stored selection references to the first selection are being used to undo the selection attributes (background color, etc.) when the second selection is made. Unfortunately, the referred-to objects are now in the bit-bucket. The modified code appears to be production-ready, i.e. hasn't failed any pre-production tests.

The solution is to put:

Tree.dndController.selectNone();

prior to first line of Layke's refreshTree solution above.

In response to meta suggestions, here it is:

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(); }
share | improve this answer edited Feb 10 '12 at 16:34
answered  Feb 9 '12 at 23:35 kcrossen
111 1 4   add a comment up vote 1 down vote

Thanks for this function, works great in my tree.

A notice to those who are new to dojo (like me)... After creation of the tree, it is needed to extend the tree with the refresh function:

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

Then you can call the function with:

dijit.byId('myTree').refresh();
share | improve this answer answered  Feb 23 '12 at 16:18 Taneeda
11 2   add a comment up vote 0 down vote

Updating your store will automatically update your tree!

  1. You need a FileWriteStore, which gives you the ability to modify your data.
  2. Use the store to fetch the items you want to update via query.
  3. Update each item returned.
  4. Then save the store and the tree will update.

    FileWriteStore.fetch({ query: { color: "red" }, onComplete: function(items){ for (var i = 0; i < items.length; i++){ FileWriteStore.setValue(items[i], "color", "green"); } FileWriteStore.save(); } });
share | improve this answer answered  Oct 10 '13 at 22:31 Tigertron
39 3   add a comment up vote 0 down vote

Layke's solution did not work for me. I am using dojo 1.9.1. My store is of type "ItemFileWriteStore" and the model of type "TreeStoreModel".

myStore = new ItemFileWriteStore({ url : "../jaxrs/group/tree" }); itemModel = new TreeStoreModel({ store : myStore, query : { id : "0" } }); parser.parse();

This works for me:

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();
share | improve this answer answered  Nov 20 '13 at 15:58 Markus Kühn
1   add a comment up vote 0 down vote

While going through these answers I've built my own method to update specific nodes once at a time and NOT need the refresh.

_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]; } } }
share | improve this answer answered  Sep 8 at 17:50 Alex Boisselle
1 1   add a comment up vote -1 down vote

Not supported at present. See here.

share | improve this answer edited Apr 16 '13 at 18:59 prongs
2,365 6 33 68 answered  Mar 23 '11 at 17:32 Andy
379 3 6        Thanks for your response Andy. Do you know an alternative tree which can be updated dynamically? –   Zion Mar 24 '11 at 17:37       Not in Dojo - but other toolkits may offer this. What I do in Dojo is put up a dojox.widget.Standby widget over the entire tree (loading icon spinner) and simply destroy the tree and bind a new tree to a new store (or repopulated store). –   Andy  Mar 25 '11 at 14:30      While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. –   ThinkingStiff Nov 14 '12 at 19:17
网友评论