I've got an ItemFileWriteStore set as a store for a tree like:
<div dojotype="dojo.data.ItemFileWriteStore" jsid="myStore" url="treeData.sat">
<div dojotype="dijit.Tree" id="myTree" store="myStore">
<div dojotype="dijit.Tree" id="myTree" store="myStore">
Works fine - tree loads properly. What I want to do without refreshing the page is programaticaly refresh the data in the tree with a server call. So in essence I want to refresh the data in the store and I assume the tree will be updated automatically. From what I've read the ItemFileWriteStore and ItemFileReadStores do not support a refresh mechanism. If you want refresh data, you recreate the datastore via javascript as in:
var newStore = new dojo.data.ItemFileWriteStore({url:treeData.sat})
Again that works fine but then how do you bind this datastore to the existing tree - my understanding is that your supposed to update the tree by updating the datastore originally bound to it. I tried just setting the store property on the tree to the new datastore but that didn't work.
I also tried using a QueryReadStore but the tree didn't want to bind to that or I did something wrong (likely).
Anyway, so how do you refresh a tree's data without reloading the page and without writing a bunch of code to manipulate the tree? Is there a way?

one solution
I solved this issue. You can do this if you create the store and tree programmatically. A refresh consists of destroying and recreating these objects. As in:
var newStore = new dojo.data.ItemFileWriteStore({url:"json.jsp"});
if (dijit.byId("navTree")) {dijit.byId("navTree").destroy()}
var newTree = new dijit.Tree({store:newStore,childrenAttr:["folders"],id:"navTree"}
, document.createElement("div"));
dojo.byId("treePlaceHolder").appendChild(newTree.domNode);
treePlaceHolder is a div used to place the tree
Almost done...
Hi!
I'm trying your trick to refresh the tree but, I don't know why, when I create and add the new tree I only see the 3 most low level entries, no sign of their branches, and no tree root. The server-side code remains unchanged and if I reload the page it works fine, so the problem must be in my dojo code. Any hints?
if (dijit.byId("roleTree")) { dijit.byId("roleTree").destroy(); } var roleTree = new dijit.Tree({store:jsonStore,id:"roleTree",label:"Roles",jsId:"roleTree"}); dojo.byId("treeContentPane").appendChild(roleTree);Thanks a lot in advance!!
works fine, but no icons
your solution work fine. I've also connected some events:
dojo.connect(newTree, 'getLabelClass', 'getNodeClass'); dojo.connect(newTree, 'getIconClass', 'getNodeIconClass'); function getNodeIconClass(item) { if (item.isFolder && item.isFolder=='true') return "configNodeFolder"; else return "configNodeItem"; }The events are fired but there's no icon. The new class provided by getLabelClass is also missing. What do i wrong?
Override, don't connect
It seems like you want your own
getNodeIconClassto return the class name. This is not possible with dojo.connect:Why not:
nevermind
I tried this solution, and the tree is refreshing but the children nodes are appearing both as children and at the root level.
I create the store programmatically and then when a different menu item is clicked, the store gets changed.
var emailStore = new dojo.data.ItemFileReadStore({id:'emailStore',url:'emailtree.json'});
function switchtree(storeName) {
if (dijit.byId("tree")) {
dijit.byId("tree").destroy();
}
var newStore = dojo.getObject(storeName);
var newTree = new dijit.Tree( {
store:newStore,
id:"tree",
query:"{type:'ci_type'}" }, document.createElement("div"));
dojo.byId("treeContainer").appendChild(newTree.domNode);
}
...
div id="treeContainer" dojoType="dijit.layout.ContentPane" layoutAlign="client"
div dojoType="dijit.Tree" id="tree" store="pcStore" query="{type:'ci_type'}"
/div
/div
...
emailtree.json
{ identifier: 'name',
label: 'name',
items: [
{ name:'Software', type:'ci_type',
children:[{_reference:'Fidelity App'}, {_reference:'Vendor App'} ] },
{ name:'Fidelity App', type:'ci_subtype' },
{ name:'Vendor App', type:'ci_subtype' },
{ name:'Document', type:'ci_type',
children:[{_reference:'Process'}, {_reference:'Policy'} ] },
{ name:'Process', type:'ci_subtype' },
{ name:'Policy', type:'ci_subtype' }
]}
...
pc_tree.json
{ identifier: 'name',
label: 'name',
items: [
{ name:'Computer', type:'ci_type',
children:[{_reference:'Monitor'}, {_reference:'Desktop'}, {_reference:'Laptop'} ] },
{ name:'Monitor', type:'ci_subtype' },
{ name:'Desktop', type:'ci_subtype' },
{ name:'Laptop', type:'ci_subtype' },
{ name:'Document', type:'ci_type',
children:[{_reference:'Process'}, {_reference:'Policy'} ] },
{ name:'Process', type:'ci_subtype' },
{ name:'Policy', type:'ci_subtype' }
]}
The initial load of the tree works fine, just when I "refresh" it, duplicates show up.
Anyone seen this before? I'm new to dojo so I hope it's something simple that I'm overlooking!
.... update ....
nevermind, i figured it out. stupid quotes
Issues with QueryReadStore
QueryReadStore isn't quite ready to be used with tree... Adding getLabel allows you to get at least the node labels - see QueryReadStore: getLabel (from FileItemReadStore). However, the real issue is that the store lacks functions for handling references and tree-like data.
destroy / recreate only/best solution
I posted a question regarding this in another thread but I wasn't clear and this seems like a better place.
I too am simply wanting to "reload" or "refresh" the entire tree from dynamic data (there are several unanswered posts on this).
I am *not* changing the data in the store so using FileItemWriteStore won't work as the onSet, etc calls want a specific node. I just want to do
tree.refresh()
or
store.refresh()
when other data changes. What I came up with was
dojo.declare('dijit.DLTree', dijit.Tree, { refresh : function () { this.store._loadFinished = false; this.store.fetch(); this.state = 'UNCHECKED'; this._expandNode(this); }, ...but this seems to cause some strange problems in IE.
Have there been enough request for dynamically refreshing a tree to open a bug?
Hack way around this
I put my tree control in a separate dijit.layout.ContentPane, and called setHref on it to reload it when the store changed. It turned out to be just too difficult to destroy and recreate the tree. It does mean that the tree control blinks when it changes, but I can live with that.