View Full Version : Loading Child Nodes
Zyclops
14 Oct 2007, 6:07 PM
I can't find a way to load all the child nodes in a tree. I'm using AsyncTreeNode as the root node but each of the children do not seam to populate node.childNodes until you call expand. I've provided the entire tree in json, and it doesn't need to any xhr requests to get the additional nodes.
I've tried setting preloadChildren: true in the treeloader settings (but that must be for something else).
The end result is i want to be able to traverse the entire tree whether or not that particular node is displayed on the screen.
Zyclops
14 Oct 2007, 6:48 PM
I've just tried hendricd's solution at http://extjs.com/forum/showthread.php?p=69834#post69834 but found that didn't load the node.childNodes either.
I've also tried copying
if(!this.loaded){
if(this.fireEvent("beforeload", this) === false){
return;
}
this.loading = true;
this.ui.beforeLoad(this);
var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
if(loader){
loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback]));
return;
}
}
out of Ext.tree.AsyncTreeNode.expand but couldn't get it to work without loadComplete.createDelegate(this, [deep, anim, callback]) expanding the node.
suggestions?
I'm having the same general problem. My current solution is to simply expand and collapse the tree. It takes a while to load, but at least it works.
Sorry I can't be more help.
hendricd
15 Oct 2007, 8:18 AM
@Zyclops: That thread only sets you up to 'not have to Asynchtree load again' any child nodes after the first expand.
I've studied the Treeloader [2.0] code, and I don't think the preloadChildren option is going to do what you (and I) wanted. (because it doesn't traverse the first level ) , but we can use it ourselves that way !
I'll offer the approach I'm using succesfully:
First, a proposed enhancement (for completeness ;) ): Return the any loader (custom or not) defined at the loader, attributes, or tree level:
Ext.override(Ext.tree.AsyncTreeNode, {
expand : function(deep, anim, callback){
if(this.loading){ // if an async load is already running, waiting til it's done
var timer;
var f = function(){
if(!this.loading){ // done loading
clearInterval(timer);
this.expand(deep, anim, callback);
}
}.createDelegate(this);
timer = setInterval(f, 200);
return;
}
if(!this.loaded){
if(this.fireEvent("beforeload", this) === false){
return;
}
this.loading = true;
this.ui.beforeLoad(this);
var loader = this.getLoader();
if(loader){
loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback]));
return;
}
}
Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback);
},
getLoader : function(){
return this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
}
});
Then for [2.0] example:
var tree = new Tree.TreePanel({
animate:false,
enableDD:false,
containerScroll: true,
autoScroll: true,
loader: new Tree.TreeLoader({dataUrl:config.url, preloadChildren:true })
// this adds a root node to the tree and tells it to expand when it is rendered
,root: new Tree.AsyncTreeNode({draggable:false,expanded:false})
,id : 'testTree'
}};
tree.root.getLoader().on('load', function(loader, node){
// convert attributes.children to childNodes without rendering
node.eachChild(loader.doPreload, loader);
});
//Now load the tree
tree.getRootNode().expand(); // load and render level 1 childNodes only
For 1.1.1 Try:
Ext.override(Ext.tree.TreeLoader, {
doPreload : function(node){
if(node.attributes.children){
if(node.childNodes.length < 1){ // preloaded?
var cs = node.attributes.children;
for(var i = 0, len = cs.length; i < len; i++){
var cn = node.appendChild(this.createNode(cs[i]));
this.doPreload(cn);
}
}
}
}
});
var loader = new Tree.TreeLoader({dataUrl:config.url});
var anode = new Tree.AsyncTreeNode({draggable:false,expanded:false, loader:loader});
loader.on('load',function(loader, node){
// convert attributes.children to childNodes without rendering
node.eachChild(loader.doPreload, loader);
});
tree.setRootNode(anode);
tree.render();
anode.expand(false,false);
[tags : Tree convert children childNodes without rendering]
robophonic
15 Oct 2007, 2:22 PM
I am trying to do this also. I just tried the above code for 1.1.1, but it didn't work. It seems that the TreeNode.beginUpdate() method does not exist in 1.1.1. Also, I believe it should be Ext.override rather than Ext.extend.
Anyone else had luck getting this to work?
robophonic
15 Oct 2007, 2:45 PM
I was able to get the Ext 2.0 code working (thanks Doug!) after fixing a typo:
tree.root.getLoader().on('load': function(loader, node){
// convert attributes.children to childNodes without rendering
node.eachChild(loader.doPreload, loader);
});
should read:
tree.root.getLoader().on('load', function(loader, node){
// convert attributes.children to childNodes without rendering
node.eachChild(loader.doPreload, loader);
});
Still no luck with 1.1.1 though...
hendricd
15 Oct 2007, 3:23 PM
OK, I merged both versions, fixed the typos, and removed the non-1.1.1 stuff.
@robophonic - I've moved all my work to 2.0+, so the 1.1.x solution still stands but haven't snapped a working model together. Review my earlier post, try again on 1.1 as let's see where you are...
robophonic
15 Oct 2007, 4:07 PM
@Doug: I just tested the new 1.1.x code and it works. Woot!
Zyclops
15 Oct 2007, 10:09 PM
hendricd: your solution worked perfectly! thank you for spending the time to type and post your solution, it saved me a lot of headaches!
This thread should be marked solved :)
hendricd
23 Oct 2007, 1:56 PM
here (http://extjs.com/forum/showthread.php?p=77130#post77130)
murrah
14 May 2009, 4:27 PM
Here is another possibility;
http://extjs.com/forum/showthread.php?t=68381
Murray
Powered by vBulletin® Version 4.1.5 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.