http://yiminghe.iteye.com/blog/313699
前一段转载了一篇
挺有启发的,觉得可以套用在extjs的管理上,管理界面 两栏布局,左边栏一棵菜单树,右面一个tabpanel,菜单树的每个菜单代表一个模块,每个模块用一个js来实现,需要时载入就行了,而不需要刚开始时把所有的模块都载进入
当点击菜单树的节点时调用:
function openGetBugsPanel(name) { var moduleId = 'BugList_tab'; //一个静态方法,表示从一个js载入了一个新的模块 Ext.ux.yiminghe.framework.core.newModule( { //模块的id moduleId: moduleId, //在哪个tabpanel新加一个模块 tabPanel: window.tabs, //模块所在js moduleURL: 'js/modules/Bugs.js', //模块所需要的参数 moduleParams: { title: name, MYBugs: false }, //如果该模块已经在tabpanel上了,怎么处理 existCallBack: function(panel) { panel.setTitle(name); panel.filters.clearFilters(); } } ); }
其实每个模块就是一个panel,加入到tabpanel 就行了,关键是要 动态构造这个panel
例如这个bugs.js
/** ajax 直接返回一个类,eval ,new **/ Ext.extend(Ext.Panel, { initComponent: function() { var bugsGrid_metaData = [ { dataIndex: 'projectId', header: '项目', width: 70, sortable: true, show: true }, { dataIndex: 'moduleId', header: '模块', width: 70, sortable: true, show: true }, { dataIndex: 'bid', header: 'Bug/Task编号', sortable: true, width: 100 }, { dataIndex: 'btitle', header: 'Bug/Task标题', width: 250, sortable: true, show: true }, { dataIndex: 'degree', header: '严重程度', width: 100, sortable: true, show: true, renderer: function(val) { return '<span style="color:green">' + val + '</span> '; } }, { dataIndex: 'status', header: '状态', width: 70, show: true, sortable: true, renderer: function(val) { return '<span style="color:red">' + val + '</span> '; } }, { dataIndex: 'who', header: '由谁创建', width: 70, sortable: true, show: true }, { dataIndex: 'assign', header: '指派给谁', width: 70, sortable: true, show: true }, { dataIndex: 'resolve', header: '由谁解决', width: 70, sortable: true, show: true }, { dataIndex: 'moduleId', header: 'moduleId', sortable: true, width: 70 }, { dataIndex: 'method', header: '解决方案', width: 100, sortable: true, show: true }, { dataIndex: 'openedTime', header: '提交时间', width: 150, sortable: true, show: true, renderer: function(val) { var d = new Date(); d.setTime(val); return '<span style="color:red">' + d.toLocaleString() + '</span> '; } } ]; Ext.grid.filter.StringFilter.prototype.icon = 'desktop/js/filter/img/find.png'; this.filters = new Ext.grid.GridFilters({ filters: [ { type: 'list', dataIndex: 'projectId', single: true, options: PROJECTS, phpMode: true, listeners: { 'update': function() { var pid = this.getValue(); if (pid == '') return; // 实例化Ext发送Ajax请求需要的Connection对象 var conn = new Ext.data.Connection(); // 发送异步请求 conn.request({ // 请求地址 url: 'bug/get_modules_ext.jsp?project_id=' + pid, method: 'GET', // 指定回调函数 callback: callback }); //回调函数 function callback(options, success, response) { if (success) { // 如果成功则使用Ext将JSON字符串转换为JavaScript对象 var jsonObj = Ext.util.JSON.decode(response.responseText); // 到这就可以取你想要的东东了 // 取消息id var m_data = jsonObj.data; filters.getFilter(1).options = m_data; filters.getFilter(1).store.loadData(m_data); } else { alert(response.responseText); } } } } }, { type: 'list', dataIndex: 'moduleId', single: true, options: [], phpMode: true }, { type: 'string', dataIndex: 'btitle' }, { type: 'list', dataIndex: 'assign', single: true, //id:'assign_filter', options: USERS, phpMode: true }, { type: 'list', dataIndex: 'who', single: true, options: USERS, phpMode: true }, { type: 'list', dataIndex: 'resolve', single: true, options: USERS, phpMode: true }, { type: 'list', dataIndex: 'status', single: true, //id:'status_filter', options: BUGSTATUSES, phpMode: true } ] }); var gridMenuDatas = [ { text: '提交Bug/Task', iconCls: 'badd', handler: function() { addBugFormPanel('提交Bug/Task'); } }, '-', { text: '编辑', iconCls: 'bedit', handler: function() { var record = this.getSelectionRecord(); createEditBugForm(record.get('bid'), record.get('btitle')); } } , '-', { text: '解决', iconCls : 'bok', handler : function() { var record = this.getSelectionRecord(); createResolveBugForm(record.get('bid'), record.get('btitle'), record.get('moduleId')); } } , '-', { text: '历史', iconCls: 'bsearch', handler: function() { var record = this.getSelectionRecord(); var moduleId = 'bugHistory_Tab' + record.get('bid'); var realId = 'bugHistory_Tab' + record.get('bid'); Ext.ux.yiminghe.framework.core.newModule( { moduleId: moduleId, realId: realId, tabPanel: window.tabs, moduleURL: 'js/modules/BugHistories.js', moduleParams: { bugId: record.get('bid'), bugName: record.get('btitle'), moduleId: record.get('moduleId') }, existCallBack: function(panel) { panel.bugHistoryGrid.reload(); } } ); } }, { text: '链接地址', iconCls: 'blist', handler: function() { var record = this.getSelectionRecord(); if (record) Ext.MessageBox.alert(record.get('btitle') + ' - Bug地址', BASEPATH + '/bug/BtsBugDetail.jsp?bugId=' + record.get('bid')); } } ]; var gridContextMenuDatas = [ gridMenuDatas[0], gridMenuDatas[2], gridMenuDatas[4], gridMenuDatas[6], gridMenuDatas[7] ]; var dbClick_g = function(record) { var moduleId = 'bugHistory_Tab'; var realId = 'bugHistory_Tab' + record.get('bid'); Ext.ux.yiminghe.framework.core.newModule( { moduleId: moduleId, realId: realId, tabPanel: window.tabs, moduleURL: 'js/modules/BugHistories.js', moduleParams: { bugId: record.get('bid'), bugName: record.get('btitle'), moduleId: record.get('moduleId') }, existCallBack: function(panel) { panel.bugHistoryGrid.reload(); } } ); }; this.bugsGrid = new Ext.ux.yiminghe.JsonGridPanel({ columns: bugsGrid_metaData, pageSize: 15, initload: true, plugins: [this.filters], viewConfig: { forceFit: true, autoFill: true }, autoScroll: true, sm: new Ext.grid.RowSelectionModel( { singleSelect: true }), dataSource: 'bug/BtsGetBugsDO_Ext.jsp', tbar: gridMenuDatas, stripeRows: true, border: false, bodyStyle: 'width:100%', isGroupHeader: false, rowcontextmenu: gridContextMenuDatas, doubleClick: dbClick_g, pageBarPlugins: [new Ext.ux.Andrie.pPageSize({ beforeText: '每页显示', afterText: '条' })] }); if (this.MYBugs) { this.filters.getFilter('assign').setValue(CURRENTUSERID); this.filters.getFilter('assign').setActive(true, true); this.filters.getFilter('status').setValue(0); this.filters.getFilter('status').setActive(true, true); } else { this.filters.clearFilters(); this.bugsGrid.reload(); } Ext.apply(this, { title: this.title, iconCls: 'tabs', autoScroll: false, id: 'BugList_tab', layout: 'fit', items: this.bugsGrid, closable: true }); //调用父类构造函数(必须) module.superclass.initComponent.apply(this, arguments); } });
可以看到在这个模块中可以调用 传过来的参数
{ title:name, MYBugs:false }
现在关键是 newModule 的实现了 ,也很简单 ,就是 ajax把 模块类区过来 ,new 一下 就是一个新的模块了 ,不过要注意一下缓存这个模块类的定义
Ext.namespace("Ext.ux.yiminghe.framework.core"); Ext.ux.yiminghe.framework.core.newModule = function(config) { //模块类的名字 var moduleId = config.moduleId; //主Tab名字 var tabPanel = config.tabPanel; //加载模块类的地址 var moduleURL = config.moduleURL; //模块实例tab的id var realId = config.realId || moduleId; //缓存模块 tabPanel.uxmodules = tabPanel.uxmodules || {}; //模块实例的配置参数 var moduleParams = config.moduleParams || {}; if (tabPanel.findById(realId)) { tabPanel.findById(realId).show(); //如果已经载入该Tab ,则调用调整函数 if (config.existCallBack) config.existCallBack(tabPanel.findById(realId)); return; } if (tabPanel.uxmodules[moduleId]) { var module = tabPanel.uxmodules[moduleId]; var moduleInstance = new module(moduleParams); var newCmp = tabPanel.add(moduleInstance); tabPanel.doLayout(); tabPanel.setActiveTab(newCmp); return; } tabPanel.loadMask.show(); Ext.Ajax.request( { method: 'GET', disableCaching: false, //utf-8 编码 url: moduleURL, success: function(response) { var module = eval(response.responseText); tabPanel.uxmodules[moduleId] = module; var moduleInstance = new module(moduleParams); var newCmp = tabPanel.add(moduleInstance); tabPanel.doLayout(); tabPanel.setActiveTab(newCmp); tabPanel.loadMask.hide(); } } ); }
总结一下流程:
1.请求一段 javascript 代码(定义一个Panel子类)
2.eval 出类型 T
3.得到新类型的实例 instance = new T
4.总控的tabpnel add instance 就可以了。