http://blog.csdn.net/leecho571/article/details/6799059
Ext4改了好多,树控件都改得自己不认识了,切入正题:
在Ext3中只要注册了'click','contextmenu',就会将Node对象传进来,代码示例:
- contextmenu : function(Ext.tree.TreeNode,Ext.EventObject e)
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)
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) {
- <span style="color:#FF0000;">Ext.data.NodeInterface.decorate(node);</span>
- 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);
- }
- }
- },
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) { <span style="color:#FF0000;">Ext.data.NodeInterface.decorate(node);</span> 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: 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的文档!!