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")