yiminghe 发表于 2013-1-23 02:54:29

Extjs 模块化动态加载js实践

前一段转载了一篇
透明加载外部 javascript 文件函数

挺有启发的,觉得可以套用在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, gridMenuDatas, gridMenuDatas, gridMenuDatas, gridMenuDatas      ];      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: ,            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:       });      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) {      var module = tabPanel.uxmodules;      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 = 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 就可以了。
页: [1]
查看完整版本: Extjs 模块化动态加载js实践