题记:研究使用ext两个星期了,从痛苦中逐渐走向明朗。
展示列表的子列表的数据时需要将当前的数据传给下一个mvc。
比如用户列表,点击一个用户查看该用户的日志列表。
首先是controller,放一个方法,注意showLog方法的两个参数,还有mvcConfig参数是我的自定义参数,供下一个mvc去调用。用Ext.applation动态添加controller。
Ext.define("admin.controller.collection.MembController", { extend: "Ext.app.Controller", views: ["collection.membList"], models: ["collection.MembModel"], stores: ["collection.MembStore"], init: function () { if (!Ext.getCmp('membList')) { var tab = Ext.create('custom.panelTab'); var view = Ext.create('admin.view.collection.membList'); tab.createTab(view); } else {
Ext.getCmp('membList').show(); } }, //查看日志 showLog: function (grid, rowIndex) { var me = this; var ctrl = Ext.create('admin.controller.collection.MembController'); var record = this.getStore().getAt(rowIndex); var rowData = grid.store.data.items[rowIndex].data; //添加controller Ext.application({ extend: 'Ext.app.Application', appFolder: "app/",//文件路径 name: 'admin', controllers: ['collection.SingleLogController'], mvcConfig: { userId: rowData.id } }); } });
在view中绑定点击事件,这个比较基础
Ext.define('admin.view.collection.membList', { extend: 'Ext.grid.Panel', requires: ['mc.date'], xtype: 'grid', title: '成员管理', id: 'membList', closable: true, store: 'collection.MembStore', initComponent: function () { var me = this; var ctrl = Ext.create('admin.controller.collection.MembController'); Ext.apply(me, { columns: [ { header: '编号', dataIndex: 'id', width: 60, }, { header: '姓名', dataIndex: 'username', width: 120, }, { header: '操作', xtype: 'actioncolumn', width: 50, sortable: false, menuDisabled: true, items: [ { icon: 'resources/css/ext/images/icons/fam/user_suit.png', tooltip: '工作日志', scope: this, handler: ctrl.showLog } ] } ] }); me.callParent(arguments); } });
接下来就是日志的controller处理了。
Ext.define('admin.controller.collection.SingleLogController', { extend: 'Ext.app.Controller', views: ['collection.memberLogList'], models: ['collection.LogModel'], stores: ['collection.SingleLogStore'], init: function () { var mvcConfig = this.getApplication().mvcConfig; //console.log('系统日志'); if (!Ext.getCmp('memberLogList')) { var tab = Ext.create('custom.panelTab'); var view = Ext.create('admin.view.collection.memberLogList'); var store = view.getStore();
store.setProxy({ type: 'jsonp', url: ajaxConfig.member.logList,//+ "?id=" + mvcConfig.userId extraParams: {//参数 //memberId: mvcConfig.userId "params": "{member:" + mvcConfig.userId + "}" }, reader: { totalProperty: 'total', root: 'results' } }); //store.load();由于第一次是自动加载执行,所以不需要手动载入 tab.createTab(view); } else { var view = Ext.getCmp('memberLogList'); var store = view.getStore(); store.setProxy({ type: 'jsonp', url: ajaxConfig.member.logList,//+ "?id=" + mvcConfig.userId extraParams: {//参数 //memberId: mvcConfig.userId "params": "{member:" + mvcConfig.userId + "}" }, reader: { totalProperty: 'total', root: 'results' } }); store.reload(); Ext.getCmp('memberLogList').show(); } }, });
注意自定义参数的获取,与store对数据的控制。
由于Ext的mvc是按文件系统(fileSystem)化分逻辑的,所以上面的代码段是分别放在不同的js文件中的,路径和类名的对应关系注意一下。
再说一下Ext的机制,模块按需加载,模块的组件间按配置与逻辑引入。首先是Ext.applation是最顶级的管理者,所有的组件(或者叫应用,英文原称Application),然后每个mvc从自己的application开始。比如点击某个dom要创建一个应用,可以点击之后执行下面代码:
var app = $(this).attr('data-app'); Ext.create(app);
很显然我用的是jquery来作为辅助实现,这里的app是“admin.app.collection.log”,然后Ext会加载js文件,文件内容如下:
Ext.define('admin.app.collection.log', { extend: 'Ext.app.Application', name: 'admin', controllers: ['collection.LogController'], mvcConfig: { userId:1 } });
这就创建了一个application,然后再由application加载配置的controller,文件式加载就完成了。上面第一个代码块中的Ext.application与上面js文件中的Ext.define基本相同。
那么有什么不同呢,说几点我的理解,未必正确仅供参考:
1、Ext是先解析再执行,那么js文件加载进来的要解析,会添加进总体控制中,在chrome中可对controller中的代码断点调试。
2、用Ext.application加载的模块是脱离控制的,文件没有进入no domain队列,所以没有调试入口。
还有几个问题没有解决:
1、在view中怎么更具data(也可以说是store)动态控制呈现的元素与行为逻辑。
2、怎样动态指定view的id,实现多tab展示。