`
yiminghe
  • 浏览: 1431712 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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[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 就可以了。

分享到:
评论
12 楼 luhouxiang 2015-05-13  
写的很不错,学习了
11 楼 zhu2217935 2012-08-28  
在使用Ext动态加载,时会出现各个模块之间相影响,导致显示不正常的问题怎么解决?
10 楼 Anthony_Zhang 2012-07-24  
请问一下? var moduleInstance = new module(moduleParams);   总是在这里退出,请问该怎么办呢,可以给个可运行的详细的例子不,谢谢了
9 楼 yiminghe 2009-12-25  
88112870 写道
请问moduleURL:'js/modules/Bugs.js',这个如何改成动态的呢?
就是根据树型菜单传过来的参数动态加载,我的树ID为Int型自增,我现在是通过命名
1.js,2.js这样来动态加载,请问楼主有好的方法能任意定义文件名找到模块么?
(模块名为中文)

功能树可以通过后台xml配置,根据权限载入不同的菜单,每个菜单读取后台的功能js文件路径
,前台点击时载入对应功能js文件即可。
8 楼 88112870 2009-12-25  
请问moduleURL:'js/modules/Bugs.js',这个如何改成动态的呢?
就是根据树型菜单传过来的参数动态加载,我的树ID为Int型自增,我现在是通过命名
1.js,2.js这样来动态加载,请问楼主有好的方法能任意定义文件名找到模块么?
(模块名为中文)
7 楼 javaAlpha 2009-11-17  
也遇到和楼主类似的问题 因为缓存引起的
6 楼 yiminghe 2009-09-22  
jacky2007 写道
我在你的基础下略修改了一下


恩,谢谢,疏忽了,当时好像也没报错。。。。
不用你那么麻烦的,函数头加上这个就行了


//缓存模块
tabPanel.uxmodules = tabPanel.uxmodules || {}; 


5 楼 jacky2007 2009-09-20  
我在你的基础下略修改了一下


Ext.ux.newModule = function (config) {  
     //模块类的名字  
     var moduleId=config.moduleId;  
     //主Tab名字  
     var tabPanel=config.tabPanel;  
     //加载模块类的地址  
     var moduleURL=config.moduleURL;  
     //模块实例tab的id  
     var realId="tab_"+ moduleId;  
     //模块实例的配置参数  
     var moduleParams=config.moduleParams||{};  
         if (tabPanel.findById(realId)) {  
              tabPanel.findById(realId).show(); 
              return;  
       }  
//这里判断了uxmodules是否定义,因为我调试时会出现tabPanel.uxmodules is undefined 的错误
       if(tabPanel.uxmodules!=undefined && tabPanel.uxmodules[moduleId]) {  
             var module =tabPanel.uxmodules[moduleId];  
             var moduleInstance = new module(moduleParams);  
             var newCmp = tabPanel.add(moduleInstance);  
             tabPanel.doLayout();  
             tabPanel.setActiveTab(newCmp);   
             return;  
       }  
     Ext.Ajax.request(  
     {  
       method: 'GET',  
       disableCaching :false,  
       //utf-8 编码  
       url: moduleURL,  
       success: function(response) {  
           var module = eval(response.responseText);
//这里定义一下tabPanel.uxmodules
           if(tabPanel.uxmodules==undefined){
        	   tabPanel.uxmodules=new Array();
           }
           tabPanel.uxmodules[moduleId] = module;  
           var moduleInstance = new module(moduleParams);
//这里设计一下module的ID,因为我的是动态的Panel,没有定义ID的
           moduleInstance.id="tab_"+moduleId;
           var newCmp = tabPanel.add(moduleInstance);  
           tabPanel.doLayout();  
                     tabPanel.setActiveTab(newCmp);  
                     tabPanel.loadMask.hide();  
                   
       }  
         }  
         );  
 }  
4 楼 yiminghe 2009-09-20  
jacky2007 写道
if(tabPanel.uxmodules[moduleId])
请问
tabPanel.uxmodules这个方法是干嘛用的?
在哪里?我看EXTJS的API没发现有这个方法


自己设的属性,用于缓存模块代码,不用每次都去下载
3 楼 jacky2007 2009-09-20  
if(tabPanel.uxmodules[moduleId])
请问
tabPanel.uxmodules这个方法是干嘛用的?
在哪里?我看EXTJS的API没发现有这个方法
2 楼 yiminghe 2009-07-27  
gkuiyj 写道
不错。我正有这样的需求, 楼主有实现了的小例子吗? 学习!····


看一下最后的 Ext.ux.yiminghe.framework.core.newModule 就行了,
很简单的,

1.请求一段 javascript 代码(定义一个Panel子类) ,
2.eval 出类型 T
3.得到新类型的实例 instance = new T
4.总控的tabpnel add instance 就可以了。
1 楼 gkuiyj 2009-07-27  
不错。我正有这样的需求, 楼主有实现了的小例子吗? 学习!····

相关推荐

Global site tag (gtag.js) - Google Analytics