`
yiminghe
  • 浏览: 1466265 次
  • 性别: 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  
不错。我正有这样的需求, 楼主有实现了的小例子吗? 学习!····

相关推荐

    Extjs3动态加载js源码

    总的来说,`Extjs3动态加载js源码`实现的动态加载管理器是一个巧妙地结合了JavaScript语言特性、浏览器API和模块化思想的解决方案。通过理解和学习这样的代码,开发者可以更好地理解如何在没有内置支持的情况下实现...

    ExtJs中引用的三个js

    6. **模块化与按需加载**:为了优化性能,ExtJS 4及以上版本引入了CMD(Command Line Compiler)和AMD(Asynchronous Module Definition)模块化加载机制。通过Sencha CMD工具,开发者可以将应用拆分为模块,并在...

    EXTJS desktop 国际化

    良好的源码结构和模块化设计能提高代码的可维护性和扩展性。 7. **实际应用示例**: - 提到的博客链接(虽然现在无法访问)可能提供了EXTJS桌面国际化的一个具体实现案例,通常包括了如何配置、加载资源文件,以及...

    ExtJS动态打包Loader

    ExtJS动态打包Loader是JavaScript开发中的一个重要工具,主要用于优化和管理Ext JS应用程序的资源加载。在大型Web应用中,由于代码量大、模块多,如何有效地加载和组织这些资源成为一个关键问题。动态打包Loader就是...

    ExtJS 4.0 的改变

    - `Ext.Loader` 类提供了动态加载 JS 文件和类的功能。通过 `setPath` 和 `require` 等方法,可以在运行时按需加载文件。启用动态加载的配置如下: ```javascript Ext.Loader.setConfig({ enabled: true, paths...

    extjs与系统切分模块设计

    - **后端服务化**:后端也应该按照模块化的原则进行设计,提供统一的服务接口,为前端组件提供所需的数据和服务。 ##### 示例代码分析 以下是两个使用ExtJS创建组件的例子: 1. **表格组件**: ```javascript ...

    EXTJS---完整数据库代码,全网唯一,非常适合EXTJS搭建框架,包含动态树,菜单等

    EXTJS是一种基于JavaScript的前端框架,它提供了丰富的组件库,用于构建富客户端应用程序。这个压缩包文件的内容看起来是一个完整的EXTJS项目,包含了数据库交互、动态树结构和菜单功能,并且集成了SpringMVC后端...

    Extjs 4.1 (MVC) 如何动态加载控制层以及session 过期该如何处理

    在EXTJS 4.1 MVC框架中,动态加载控制层是一项关键功能,它允许你在运行时根据需求加载特定的控制器,以实现模块化的应用程序。在处理动态加载控制器时,我们需要确保避免重复加载已经加载过的控制器,以免导致性能...

    ExtJS 2.3/3.0 定制你所需要的模块

    1. **模块化开发**:在ExtJS中,模块化开发是一种常见的方法,它允许将应用分解为可重用的组件或模块。通过定义自己的类和扩展内置类,可以创建定制的模块,以满足特定的需求。 2. **自定义组件**:如果你发现标准...

    ExtJs-3.2.0.rar

    这种模块化的设计思路使得代码复用性高,减少了工作量。 8. **数据绑定** 数据绑定是ExtJS的一个强大特性,它允许组件与数据模型直接关联,当模型数据发生变化时,界面会自动更新,反之亦然。这种实时的数据同步...

    ExtJS开发插件及Ext包

    - 在开发ExtJS应用时,遵循最佳实践至关重要,例如使用SASS预处理器进行样式管理,使用CMD进行模块化构建,以及遵循组件设计原则,使代码可复用且易于维护。 - 保持代码结构清晰,合理组织目录结构,以及使用命名...

    extJS的相关学习资料

    此外,它可能还会涉及ExtJS的模块化开发、性能优化等方面,帮助你提高开发效率并提升应用质量。 学习ExtJS的过程中,理解组件模型、事件系统、MVC架构,以及如何有效地组织代码结构是非常重要的。同时,不断实践和...

    ExtJs4.0 表单提交Demo

    ExtJs 4.0 是一款强大的JavaScript框架,用于构建富客户端Web应用。它提供了一整套组件、布局和数据管理工具,使得开发者可以构建出功能丰富、交互性强的用户界面。在“ExtJs4.0 表单提交Demo”中,我们将深入探讨...

    ExtJS 3.4 源码包

    通过研究ExtJS 3.4的源码,开发者不仅可以学习到JavaScript的高级用法,还能掌握前端开发的最佳实践,为构建高性能、交互性强的Web应用打下坚实基础。同时,这个源码包对于想要深入了解JavaScript框架工作原理的人来...

    php+ExtJS 开发实战

    - **模块化**: 通过模块化的思想,可以将复杂的系统分解成多个独立的部分,每个部分负责不同的功能,有助于管理和维护大型项目。 #### 4. ExtJS与PHP的集成 在实际开发中,ExtJS作为前端框架,通常需要与后端语言...

    extjs 4.0 extjs

    MVC模式使得代码更加模块化,提高了可维护性和可扩展性。 `ext-all-debug-w-comments.js`, `ext-all-debug.js` 和 `ext-all.js` 是ExtJS的核心库文件,分别代表带有注释的调试版本、调试版本和生产版本。调试版本...

    ExtJS中文手册.doc

    同时,ExtJS采用模块化的设计,允许按需加载,减少了页面的体积和加载时间。 在工具方面,ExtJS提供了一个名为Sencha CMD的命令行工具,用于自动化构建过程,如编译Sass,压缩JavaScript,管理依赖关系等。此外,...

    spring+extjs项目文件

    Spring以其强大的企业级应用支持和模块化设计,成为Java开发的主流选择,而ExtJS则是一款功能丰富的JavaScript前端框架,擅长构建富交互的用户界面。当这两者结合,能够构建出高效、用户体验优良的人力资源管理系统...

    extjs小例子

    EXTJS是一种基于JavaScript的前端开发框架,主要用于构建富互联网应用程序(Rich Internet Applications,RIA)。...通过分析和实践这个"portal"示例,你将能够掌握EXTJS构建动态、可配置界面的关键技术。

    extjs2.2开发实战项目 已经发布运行

    EXTJS2.2推荐使用MVC模式,将模型、视图和控制器分离,保持代码模块化。项目中的文件结构和命名约定,体现了这一良好实践。 8. **性能优化**:EXTJS2.2提供了多种性能优化手段,如延迟加载、缓存策略等。项目中可能...

Global site tag (gtag.js) - Google Analytics