第二步:重写Ext.tree.TreePanel类的registerNode方法,记tree注册treeid为真实
ID
Ext.override(Ext.tree.TreePanel,{ getNodeByTreeId : function(treeid){ return this.nodeHash[treeid]; }, registerNode : function(node){ this.nodeHash[node.attributes.treeid] = node; }, unregisterNode : function(node){ delete this.nodeHash[node.attributes.treeid]; } });
第三步:重写Ext.tree.TreeNode类的ensureVisible 方法,使其调用的getNodeByTreeId为treeid
Ext.override(Ext.tree.TreeNode,{ ensureVisible : function(callback){ var tree = this.getOwnerTree(); tree.expandPath(this.parentNode.getPath(), false, function(){ var node = tree.getNodeByTreeId(this.attributes.treeid); // Somehow if we don't do this, we lose changes that happened to node in the meantime tree.getTreeEl().scrollChildIntoView(node.ui.anchor); Ext.callback(callback); }.createDelegate(this)); } });
第四步:重写Ext.tree.TreeEventModel类getNode方法,使其调getNodeByTreeId方法
Ext.override(Ext.tree.TreeEventModel,{ getNode : function(e){ var t; if(t = e.getTarget('.x-tree-node-el', 10)){ var id = Ext.fly(t, '_treeEvents').getAttributeNS('ext', 'tree-node-id'); if(id){ return this.tree.getNodeByTreeId(id); } } return null; } });
经过上面的4步以后,“ext2的tree id不唯一的解决方法”一文中还有第5步,写的不是很详细
第五步:重写Ext.tree.TreeNodeUI类,我这里采用的是继承,覆盖renderElements方法
Ext.override(Ext.tree.TreeNodeUI,{ renderElements:function(D,I,H,J){ this.indentMarkup=D.parentNode?D.parentNode.ui.getChildIndent():""; var E=typeof I.checked=="boolean"; var B=I.href?I.href:Ext.isGecko?"":"#"; var C=["<li class=\"x-tree-node\"><div ext:tree-node-id=\"",D.attributes.treeid,"\" class=\"x-tree-node-el x-tree-node-leaf x-unselectable ",I.cls,"\" unselectable=\"on\">","<span class=\"x-tree-node-indent\">",this.indentMarkup,"</span>","<img src=\"",this.emptyIcon,"\" class=\"x-tree-ec-icon x-tree-elbow\" />","<img src=\"",I.icon||this.emptyIcon,"\" class=\"x-tree-node-icon",(I.icon?" x-tree-node-inline-icon":""),(I.iconCls?" "+I.iconCls:""),"\" unselectable=\"on\" />",E?("<input class=\"x-tree-node-cb\" type=\"checkbox\" "+(I.checked?"checked=\"checked\" />":"/>")):"","<a hidefocus=\"on\" class=\"x-tree-node-anchor\" href=\"",B,"\" tabIndex=\"1\" ",I.hrefTarget?" target=\""+I.hrefTarget+"\"":"","><span unselectable=\"on\">",D.text,"</span></a></div>","<ul class=\"x-tree-node-ct\" style=\"display:none;\"></ul>","</li>"].join(""); var A; if(J!==true&&D.nextSibling&&(A=D.nextSibling.ui.getEl())){ this.wrap=Ext.DomHelper.insertHtml("beforeBegin",A,C); }else{ this.wrap=Ext.DomHelper.insertHtml("beforeEnd",H,C); } this.elNode=this.wrap.childNodes[0]; this.ctNode=this.wrap.childNodes[1]; var G=this.elNode.childNodes; this.indentNode=G[0]; this.ecNode=G[1]; this.iconNode=G[2]; var F=3; if(E){ this.checkbox=G[3]; F++; } this.anchor=G[F]; this.textNode=G[F].firstChild; } });
注:在我的项目中没有去添加这个步骤,因为我采用了文章开头说的TreeCheckNodeUI.js,不过对这个js作了小的调整。修改的地方如下:
主要是这句:
var buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.treeType+n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
在上面一句用到了n.treeType这个属性,在ext-all.js里面是没有这个属性的,这就需要我们自己添加上去。代码如下:(修改ext-all.js)
Ext.data.Node=function(A){this.attributes=A||{};this.leaf=this.attributes.leaf;this.treeType=this.attributes.treeType;this.id=this.attributes.id;。。
上面就是js部分修改的地方,那么在程序里用JsonUtils.write();方法写树形结构的时候,就需要把treeType加入进去。