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

你可能感兴趣的:(JavaScript,Ajax,json,jsp,ext)