• Extjs4.1.x使用Application动态按需加载MVC各模块


    我们知道Extjs4之后提出了MVC模块开发,将以前肥厚的js文件拆分成小的js模块[modelviewcontrollerstoreformdata等],通过controller拼接黏合,提高了js代码的重用性,可阅读性,更加适合团队的开发。

    js采用mvc后必定会带来一个问题,如何高效的加载各个js小文件?(源码)

    官方的例子是统一采用了一个Ext.Application入口:

    Ext.application({  
            name: 'WMS',  
            appFolder: 'ExtJs/App',  
            autoCreateViewport:true,  
            controllers: [       'controller1','controller2','controller3' 
            ],  
            launch: function() {  
                   //  
            }  
        });

    由于一个应用程序只有一个入口也就是一个application,这样会带来一个问题,我一个项目有众多的controller文件,需要在系统启动的时候加载所有的js文件,这明显不是我们想要的,我们想按需加载,在页面呈现的时候按需加载js各个模块文件。

    看下面的框架例子,说的直白一点也就是我单击功能菜单树的“组织架构”,打开新的tab页面的时候,再加载所需要的js文件。

    image

    由于tab页面加载不是采用iframe的方式,这样就会带来更多的问题,毕竟他是和整个框架式一体的,需要考虑的问题不少。好处也很明显,不用每次都加载必备的Extjs库文件等。

    //tab页面加载方法  
        NodeClick: function (view, record) {  
                if (record.data.leaf == true) {  
                    var panel = Ext.getCmp(record.id);  
                    if (!panel) {  
                        panel = {  
                            id: record.id,  
                            closable: true,  
                            title: record.data.text,  
                            iconCls: record.data.iconCls,  
                            autoScroll: true,  
                            border: false,  
                            layout: 'fit',  
                            autoLoad: {//采用autoload方式  
                                url: record.data.url,  
                                scope: this,  
                                scripts: true,  
                                text: '页面加载中,请稍候....' 
                            }  
                        };  
                        this.openTab(panel, record.id);  
                    } else {  
                        var main = Ext.getCmp("ViewPortCoreTab");  
                        main.setActiveTab(panel);  
                    }  
                }  
            },  
            openTab: function (panel, id) {  
                var o = (typeof panel == "string" ? panel : id || panel.id);  
                var main = Ext.getCmp("ViewPortCoreTab");  
                var tab = main.getComponent(o);  
                if (tab) {  
                    main.setActiveTab(tab);  
                } else if (typeof panel != "string") {  
                    panel.id = o;  
                    var p = main.add(panel);  
                    main.setActiveTab(p);  
                }  
            },

    image

    在组织架构页面的写法如下(没有整理,单独归档js)

    @{  
            ViewBag.Title = "组织架构管理";  
        }  
         
        <script>  
            Ext.define('Module.UserModule', {  
                extend: 'Ext.app.Application',  
                id:"Org",  
                name: 'AM',  
                appFolder: '/ExtJs/App',  
                controllers: ["Users"],  
                launch: function () {  
                }  
            });  
            Ext.require("Module.UserModule", function () {  
                var app = Ext.create('Module.UserModule');          //需求创建user办理模块的app  
                Ext.onReady(function () {                                 //必需要等user办理模块的app创建完成后才执行  
                    var main = new Ext.Panel({  
                        border: false,  
                        layout: 'fit',  
                        items: [{  
                            xtype: 'userlist' 
                        }]  
                    });  
                    //autoload方式,需要添加到tab,否则默认会是整个viewport,那就坏事喽  
                    Global.ExtTabDoLayout(main);  
                });  
            });  
        </script>

    好了,到目前为止,解决了按需加载js模块的方法。

    但是新的问题又来了[ExtJs这玩意真的是很痛苦,几度放弃的边缘],引入了新的application后,页面的原始事件被刷新掉了,不管用了,估计是

    init: function () {  
                this.control({//这里导致我整个框架的单击树节点的事件没有了(估计是this的问题)  
                    'panel > userlist dataview': {  
                        itemdblclick: this.editUser  
                    },  
                    'useredit button[action=save]': {  
                        click: this.updateUser  
                    }  
                });  
            },

    上一篇发现实现上还是有问题,有很多理解不到位的地方,晚上详细解决下了,终于实现MVC各模块按需加载了,哈皮。

    上篇文章中,关于ExtJs这个玩意的评论就跟java和.Net那个好一样,既然上了贼船,就难下了,而且对于企业级的应用我个人觉得Extjs框架还是不错的,尤其是没有UI设计的团队(苦逼的程序员就兼UI吧),起码难得发现一个做的比较好的UI框架(国产的miniUI貌似看的过去,其他的就有点扯淡了[什么EasyUI、Dojo、 JqueryUI等等]),2年前选择了Extjs2.0之后收费了,停了一段时间,后面做了比较久的Ext.Net(主要是开发效率高),现在还是转回了ExtJs4,又到了起点,悲吹....干吧!

    扯远了,回归正题:中午的时候碰到一个问题,控件的事件被注销了,思索了下考虑是application重新创建覆盖主框架的问题,那么也就是说整个系统只能采用一个application,那么如何动态的加载controller呢?只要动态的加载了controller,其他的view、 store等都会被一次加载。 

    image

    首先我们需要定义一个公共方法让application加载controller,

    //动态加载js模块,****重要  
        var application;  
        Ext.Loader.setConfig({ enabled: true });  
        Ext.require([  
            'Ext.app.Application',  
            'Ext.app.Controller' 
        ]);  
        Ext.app.Controller.implement({  
            //MVC 加载模型  
            loadModel: function () { },  
            //MVC 加载视图  
            loadView: function () { },  
            getApplication: function () {  
                return this.application;  
            }  
        });  
        Ext.app.Application.implement({  
            //MVC 加载控制器  param {String/Array} controllers  
            loadModule: function (controllers) {  
                var me = this;  
                var controllers = Ext.Array.from(controllers), ln = controllers.length, i, controller;  
                for (i = 0; i < ln; i++) {  
                    var name = controllers[i];  
                    if (!this.controllers.containsKey(name)) {  
                        controller = Ext.create(  
                                this.getModuleClassName(name, 'controller'), {  
                                    application: this,  
                                    id: name  
                                });  
                        this.controllers.add(controller);  
                        // 优先加载模型  
                        controller.loadModel();  
                        controller.init(this);  
                        controller.onLaunch(this);  
                        //动态构建视图 & 绑定模型数据  
                        controller.loadView();  
                    }  
                }  
            }  
        });  
        /*****END************/

    image

    当我们单击功能节点树的"组织架构"的时候,开始加载Controller的Org.js,是的只需要加载这一个就可以了,其他的他会自动加载,也是MVC的优点:

    @{  
            ViewBag.Title = "组织架构管理";  
        }  
         
        <script>  
            /*      
            写法一:  
            application.loadModule("Users");  
            //var module = application.getController("Users");     
            //var viewName = module.views[1];  
            //alert(viewName);  
            //var view = module.getView("user.List");或者是viewName  
            //var panel = view.create();  
            //Global.ExtTabDoLayout(panel);  
         
            写法二:  
            var main = new Ext.Panel({  
                border: false,  
                layout: 'fit',  
                items: [{  
                    xtype: 'userlist'  
                }]  
            });  
            Global.ExtTabDoLayout(main);  
         
            */ 
         
            application.loadModule("Org");  
            var main = new Ext.Panel({  
                border: false,  
                layout: 'border',  
                items: [{ xtype: 'OrgTree' }, { xtype: 'OrgUserGrid' }]  
            });  
           //添加到tab里  
            Global.ExtTabDoLayout(main);  
        </script>

    这样整个组织架构的页面搭建就实现了,而且是按需加载本模块的,各个事件不会冲突。

    具体的代码太多了见附件。

    这还没开始写业务逻辑呢,就这么蛋疼了写了这一堆的js文件,看来整个架构完成,哥哥我非死即伤( ⊙o⊙ )哇...............

  • 相关阅读:
    阅读第十到十二章有感
    程序测试学习之5.2作业
    作业五——封装
    作业4 阅读《构建之法》第6 第7章有感
    汉堡包~~~
    作业3 阅读《构建之法》1-5章
    结对子实验——小学生四则运算
    小学生四则运算程序
    学会提问(转)
    error of “omission” and “commission”
  • 原文地址:https://www.cnblogs.com/asks/p/4183515.html
Copyright © 2020-2023  润新知