Ext4改了好多,树控件都改得自己不认识了,切入正题:
在Ext3中只要注册了'click','contextmenu',就会将Node对象传进来,代码示例:
contextmenu : function(Ext.tree.TreeNode,Ext.EventObject e)
这样到话就可以直接得到node对象,但在Ext4中变化好大了,传进来的没有Node对象,代码示例:
itemcontextmenu( Ext.view.View this, Ext.data.Model record, HTMLElement item, Number index, Ext.EventObject e)
传进来到参数得不到Node对象就无法操纵树,今天看了源码,看了文档终于研究了好久才得出了一个结论:
其实record里面就包含了Ext3中treeNode到方法,recorrd就是Node对象。区别在于,Ext4中record只是完全跟数据相关,不跟页面展示发生关系,页面展示通过Ext.tree.View实现。
下面所一段Ext.tree.View中的源码:
setNode: function(node) { var me = this; if (me.node && me.node != node) { me.mun(me.node, { expand: me.onNodeExpand, collapse: me.onNodeCollapse, append: me.onNodeAppend, insert: me.onNodeInsert, remove: me.onNodeRemove, sort: me.onNodeSort, scope: me }); me.node = null; } if (node) { Ext.data.NodeInterface.decorate(node); me.removeAll(); if (me.rootVisible) { me.add(node); } me.mon(node, { expand: me.onNodeExpand, collapse: me.onNodeCollapse, append: me.onNodeAppend, insert: me.onNodeInsert, remove: me.onNodeRemove, sort: me.onNodeSort, scope: me }); me.node = node; if (node.isExpanded() && node.isLoaded()) { me.onNodeExpand(node, node.childNodes, true); } } },
标红到为关键代码,Ext.tree.View获得Ext.data.Model对象之后,将Ext.data.NodeInterface中Node相关的属性复制到Ext.data.Model中,看decorate的实现:decorate: function(record) { if (!record.isNode) { var mgr = Ext.ModelManager, modelName = record.modelName, modelClass = mgr.getModel(modelName), idName = modelClass.prototype.idProperty, instances = Ext.Array.filter(mgr.all.getArray(), function(item) { return item.modelName == modelName; }), iln = instances.length, newFields = [], i, instance, jln, j, newField; modelClass.override(this.getPrototypeBody()); newFields = this.applyFields(modelClass, [ {name: idName, type: 'string', defaultValue: null}, {name: 'parentId', type: 'string', defaultValue: null}, {name: 'index', type: 'int', defaultValue: null}, {name: 'depth', type: 'int', defaultValue: 0}, {name: 'expanded', type: 'bool', defaultValue: false, persist: false}, {name: 'checked', type: 'auto', defaultValue: null}, {name: 'leaf', type: 'bool', defaultValue: false, persist: false}, {name: 'cls', type: 'string', defaultValue: null, persist: false}, {name: 'iconCls', type: 'string', defaultValue: null, persist: false}, {name: 'root', type: 'boolean', defaultValue: false, persist: false}, {name: 'isLast', type: 'boolean', defaultValue: false, persist: false}, {name: 'isFirst', type: 'boolean', defaultValue: false, persist: false}, {name: 'allowDrop', type: 'boolean', defaultValue: true, persist: false}, {name: 'allowDrag', type: 'boolean', defaultValue: true, persist: false}, {name: 'loaded', type: 'boolean', defaultValue: false, persist: false}, {name: 'loading', type: 'boolean', defaultValue: false, persist: false}, {name: 'href', type: 'string', defaultValue: null, persist: false}, {name: 'hrefTarget',type: 'string', defaultValue: null, persist: false}, {name: 'qtip', type: 'string', defaultValue: null, persist: false}, {name: 'qtitle', type: 'string', defaultValue: null, persist: false} ]); jln = newFields.length; for (i = 0; i < iln; i++) { instance = instances[i]; for (j = 0; j < jln; j++) { newField = newFields[j]; if (instance.get(newField.name) === undefined) { instance.data[newField.name] = newField.defaultValue; } } } } Ext.applyIf(record, { firstChild: null, lastChild: null, parentNode: null, previousSibling: null, nextSibling: null, childNodes: [] }); record.commit(true); record.enableBubble([ "append", "remove", "move", "insert", "beforeappend", "beforeremove", "beforemove", "beforeinsert", "expand", "collapse", "beforeexpand", "beforecollapse", "sort" ]); return record; },在decorate方法中复制了一系列树节点到相关属性和事件到Ext.data.Model中,并重写了getPrototypeBody方法在getPrototypeBody方法中,将树节点到操作复制到了Ext.data.Model中,比如:insertChild,remove,eachChild等方法,具体可以去查Ext.data.NodeInterface的文档!!