PDA

View Full Version : [FIXED-278][2.x,3.x] AsyncTreeNode's loader is overridden by the one from treePanel



xsuniwov
12 Aug 2008, 2:54 PM
We found Ext 2.2 starts to support literal config for TreeNode, AsyncTreeNode and TreeLoader. That helps us a lot and thank you!

Here is still a problem on AsyncTreeNode's TreeLoader. For example:

var tree = new Ext.tree.TreePanel({
xtype: 'treepanel',
el:'tree',
animate:true,
autoScroll:true,
containerScroll:true,
autoHeight: true,
loader: {dataUrl: "http://server/webapps/treePanel.jsp (http://server/webapps/treePanel.jsp)"},
root:
{
text: 'root2',
draggable:false, // disable root node dragging
loader: {dataUrl: "http://server/webapps/treeNode.jsp (http://server/webapps/treeNode.jsp)"},
id:'root',
expanded: true
}
});
tree.render();
});

"http://server/webapps/treeNode.jsp" never gets called. The same thing applies to all the children nodes. Even if they have different loader configured, Ext still uses TreePanel's loader to create the next level nodes.

Debug through the source codes, I found two suspicious places:

1. In TreeLoader.js
...
createNode : function(attr){
// apply baseAttrs, nice idea Corey!
if(this.baseAttrs){
Ext.applyIf(attr, this.baseAttrs);
}
if(this.applyLoader !== false){
attr.loader = this;
}
...

It seems like it doesn't honor node's own loader. what is "applyLoader" used for?

2. In AsyncTreeNode.js
Ext.tree.AsyncTreeNode = function(config){
this.loaded = config && config.loaded === true;
this.loading = false;
Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);
/**
* @event beforeload
* Fires before this node is loaded, return false to cancel
* @param {Node} this This node
*/
this.addEvents('beforeload', 'load');
/**
* @event load
* Fires when this node is loaded
* @param {Node} this This node
*/
/**
* The loader used by this node (defaults to using the tree's defined loader)
* @type TreeLoader
* @property loader
*/
};

It mentions the loader, but doesn't initialize it from "config", why?

I made two changes at these places and it seems make it work:
1.
...
if(this.applyLoader !== false){
attr.loader = attr.loader || this;
}
...

2.
...
var l = config.loader;
if(!l){
l = new Ext.tree.TreeLoader({
dataUrl: this.dataUrl
});
}else if(typeof l == 'object' && !l.load){
l = new Ext.tree.TreeLoader(l);
}
this.loader = l;
...

Not sure if these are right fixes though.

jsakalos
16 Aug 2008, 8:13 AM
Do you think this is a bug? I can move this thread to Bugs forum then.

xsuniwov
18 Aug 2008, 9:44 AM
Can you confirm this is a bug or we just use it wrong? If yes, sure, you can move it to the right place.

jsakalos
18 Aug 2008, 10:15 AM
I haven't tested it personally but if node's loader is not called but the tree's one, as you say, it looks like bug. If nowhere else then in docs.

Moving the thread to bugs.

bosok
28 Aug 2008, 7:55 AM
I think this is a bug, I am experiencing the same phenomenon. I cannot define different Treeloaders for different nodes in a tree...

evant
28 Aug 2008, 8:21 AM
Agreed, the tree loader should only inherit if the node hasn't specified a loader.

However, if there is no loader defined on a node and the parent node has a loader, which loader should the node use? It would be most logical for it to be the loader of the parent.

xsuniwov
28 Aug 2008, 9:54 AM
I think it is more logical to use parent's loader than to use treePanel's one.

Animal
28 Aug 2008, 11:54 AM
I agree. That way you can have branches loaded from different loaders which offers flexibility. I seem to remembert posting a Feature Request about this.

Animal
28 Aug 2008, 11:55 AM
http://extjs.com/forum/showthread.php?t=39170

manna
28 Oct 2008, 7:29 AM
I am pretty new at ExtJS, have been playing with trees a bit: I have configured a loader for my root node, and the child nodes need to use the loader configured in the tree panel. However, it seems that the logic implemented by this discussion means that the child nodes will inherit the root's loader?

How can I have the root node use one loader, and the child nodes have their own?

Condor
28 Oct 2008, 7:45 AM
Without changing the current Ext JS code your only option is to set applyLoader:false in the root loader and specify loaders in the child node attributes.

ps. Shouldn't the correct fix be:

Ext.override(Ext.tree.TreeLoader, {
createNode : function(attr){
if(this.baseAttrs){
Ext.applyIf(attr, this.baseAttrs);
}
if(this.applyLoader !== false && !attr.loader){
attr.loader = this;
}
if(typeof attr.uiProvider == 'string'){
attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
}
if(attr.nodeType){
return new Ext.tree.TreePanel.nodeTypes[attr.nodeType](attr);
}else{
return attr.leaf ?
new Ext.tree.TreeNode(attr) :
new Ext.tree.AsyncTreeNode(attr);
}
}
});

manna
30 Oct 2008, 12:56 AM
Hi Condor, thanks that did the trick!

trasherdk
8 Aug 2009, 2:59 AM
Cool.

I've been struggling with this for the last week. This really did hit the spot.

Thanks a lot.

samson85
1 Oct 2009, 6:08 AM
As of ExtJS 3 this misbehavior is still present. Are there any plans to change this?

Condor
1 Oct 2009, 6:35 AM
I'll move this thread to the 3.0 Bugs section.

evant
1 Oct 2009, 6:52 AM
Fix applied to svn in rev #5440 for patch release 3.0.3.

Fix also applied to the 2.x branch.