ExtJs 通过分析源代码解决动态加载Controller的问题

通过分析源代码解决动态加载Controller的问题

最近在研究ExtJs(4.2.0)的MVC开发模式,具体Extjs的MVC如何使用这里不解释,具体参见ExtJs的官方文档。这里要解决的问题是如何解决在使用MVC模式时动态加载Controller。

这是正常的写法,在Application里配置Controller

Application

Ext.application({
    ...

    controllers: [
        'Users'
    ],

    ...
});

Controller

Ext.define('AM.controller.Users', {
    extend: 'Ext.app.Controller',

    stores: [
        'Users@AM.store'
    ],

    models: [
        'User@AM.model'
    ],

    views: [
        'Edit@AM.view.user',
        'List@AM.view.user'
    ],

    refs: [
        {
            ref: 'usersPanel',
            selector: 'panel'
        }
    ]
    ...
});

这样的话ExtJs在初始化我们的Application的时候会去加载配置的[controllers],然后Controller里又依赖了[view][store][model]。

这样的话ExtJs会动态加载这些类的JS文件.这是常规的方式,这种方式的一个问题就是 如果我们的应用程序很大,那么会在Application里配置很多的controller。那么就会导致ExtJs在第一次加载时速度非常的慢,那么如何解决这个问题呢,接下来就是我的解决办法。

 

首先想到的就是查看Ext.app.Application这个类的源代码 看看它是如何加载Controller的

打开源代码我们首先看它的构造函数

    constructor: function(config) {
        var me = this;

        //<debug>
        if (Ext.isEmpty(me.name)) {
            Ext.Error.raise("[Ext.app.Application] Name property is required");
        }
        //</debug>
     
        me.callParent(arguments);
        
//调用继承至Ext.app.Controller的方法 设置初始化状态 me.doInit(me); //初始化命名空间 me.initNamespace();

//这个方法是核心方法 由它来初始化controller的 那么我们看看这个方法到底做了什么 me.initControllers();

//初始化后调用一些事件(不重要) me.onBeforeLaunch(); me.finishInitControllers(); }
    initControllers: function() {
        var me = this,
            controllers = Ext.Array.from(me.controllers);

        me.controllers = new Ext.util.MixedCollection();

        for (var i = 0, ln = controllers.length; i < ln; i++) {
            me.getController(controllers[i]);
        }
    }

下面来解释一下initControllers方法

controllers: [
        'Users'
],
1 拿到配置的 controllers(在application中定义地的) 并转换成数组
controllers = Ext.Array.from(me.controllers);

2 设置me.controllers = new Ext.util.MixedCollection();(类似于java的HashMap key value形式)
me.controllers = new Ext.util.MixedCollection();

3 循环controllers 调用了application的getController('你配置的controller')方法,并把每一个controller传过去.那么这里就是('Users')
for (var i = 0, ln = controllers.length; i < ln; i++) {
            me.getController(controllers[i]);
    }

其实本文的重点就是Application.getController(name)方法

    getController: function(name) {
        var me          = this,
            controllers = me.controllers,
            className, controller;

        controller = controllers.get(name);

        if (!controller) {
            className  = me.getModuleClassName(name, 'controller');

            controller = Ext.create(className, {
                application: me,
                id:          name
            });

            controllers.add(controller);

            if (me._initialized) {
                controller.doInit(me);
            }
        }

        return controller;
    },

这里就可以根据每个Controller进行加载了,加载完毕以后会调用doInit方法对Controller进行初始化

if (me._initialized) {
                controller.doInit(me);
            }

看到这里已经明白了Application加载Controller的原理,那么我们就可以根据需要进行动态加载了

MyApplication.getController("Users")

 

 

 

posted @ 2013-07-08 13:34  大新博客  阅读(1802)  评论(2编辑  收藏  举报