昨天为了项目需要在做异步加载树时,碰到一个每次点击节点都重新,而且要把数据共享给Grid。有过一些想法,可是步骤都太多,而且感觉代码太乱。所以就想去看看Ext代码是如何实现树的加载和异步加载树是如何生成的。
看了一下发现,在Ext.tree.AsyncTreeNode中有一个属性叫loaded。
Ext.tree.AsyncTreeNode就是通过这个标识位来识别该节点是否已经加载。如果loaded为true时,即为已经加载过,而以后点击,则节点展开时不再从后台加载。所以我们只要实现在节点收起时把这个loader=false;就可以实现我们所需要的功能。
于是我自定义了一个Ext.ui.EproAsyncTreeNode,重写collapse方法,
Ext.ui.EproAsyncTreeNode = Ext.extend(Ext.tree.AsyncTreeNode, {
???collapse : function(deep, anim) {
????this.loaded = false;
????Ext.ui.EproAsyncTreeNode.superclass.collapse.call(this, deep,
??????anim);
???}
??});
这样后,我又试了一下,又出现了一个问题,就是只有根节点才实现这样功能,而其它的节点都没有该功能。又花了点时间,还是没有发现什么不同。最后想到Ext.tree.TreePanel是如何动态生成节点,一看,果然还有一个重要的地方没有改。Ext.tree.TreePanel生成节点的方法createNode一直还是使用了默认的Ext.tree.AsyncTreeNode。于是就修改这里,再次测试,果然达到我们想要的结果。
Ext.namespace("Ext.ui");
Ext.ui.EproTreeLoader = Ext.extend(Ext.tree.TreeLoader,{
??? createNode : function(attr){
??????? // apply baseAttrs, nice idea Corey!
??????? if(this.baseAttrs){
??????????? Ext.applyIf(attr, this.baseAttrs);
??????? }
??????? if(this.applyLoader !== false){
??????????? 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.ui.EproAsyncTreeNode(attr);//自定义的动态加载节点
??????? }
??? }
});
根据你的意思,我都把loader设置成false,可以还不行。貌似官方例子没有这个问题啊