在Extjs中,為了滿足動態載入js檔案的過程,經過本人測試,可採用以下兩種方式:
1、在一個application執行個體下
在此情況下,可採用Ext.require()函數進行動態按需載入js檔案。以載入一個controller為例:
Ext.require('MyApp.controller.event.Bases',function(){ MyApp.getController('event.Bases').init(); tab = me.getTabpanel().add({ xtype: view, closable: true, animate : true, iconCls: 'icon-rights', title: record.raw.menuName });
此controller為MyApp.controller.event.Bases,在才用Ext.require()載入指定檔案時,只會通過網路擷取此檔案,即
MyApp.controller.event.Bases.js檔案,此時並未載入controller所依賴的model,store,view,此時還需要調用
MyApp.getControoler()方法對所獲得的controller檔案進行初始化,調用其init()方法將載入所依賴的store,model和view檔案。另外,
通過查看Ext.app.Application的getController源碼:
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; },
通過閱讀getController檔案源碼,可看出:通過getController方法,首先獲得對應controller對應controller的className,然後通過Ext.create()
方法建立controller,並將此controller加入到對應MyApp執行個體的controllers中,最重要的一點,然後調用controller.doInit()方法初始化controler,
載入對應的store,model,view檔案以及調用init()方法,所以在單application下,可以簡化動態載入過程:
MyApp.getController('event.Bases').init();
為使Ext.Loader動態載入開啟,需進行如下設定:
Ext.Loader.setConfig({enabled : true});2、多執行個體application
首先以ExtJs 4.1版本進行測試,在大系統下,可對業務進行模組劃分,各個模組可以單獨建立application,當需要載入指定模組時,建立對應的
application,並載入其依賴檔案,實現各個模組的按需載入,相比一次性載入所有檔案相比,系統的啟動載入速度將提高。
在載入各個模組時,可以才用loader屬性或者載入iframe完成,在iframe用法中將會重複負載檔案,這裡不予介紹,下面主要介紹一下loader
方法。 在ExtJs4.1 版本下,假定左邊為treepanel,右邊為tabpanel,點擊左邊的樹節點將分模組載入對應的application,並在右側的tabpanel
中進行顯示,當點擊左側樹節點時,在其點擊相應函數中添加:
panel = tab.add(Ext.create('Ext.panel.Panel', { id : record.raw.id, title : record.raw.text, layout : 'fit', loader : { url : record.raw.url, autoLoad : true, scripts : true }, autoShow : true, autoRender : true, tabTip : record.raw.text, border : false, renderTo : Ext.getBody(), closable : true }));
在loader屬性中,url為指定載入的html檔案,如app/logApp/logList.html,在此html中引用此模組對應的js檔案,其格式如下:
<script type="text/javascript" src="app/logApp/logListApp1.js"></script>
在html中增加標籤,作用是將此模組建立的頁面渲染到此標籤上,下面將會講到,如果沒有此標籤,頁面將無法渲染,而且在一個系統下,
各模組的的id必須為唯一。html所引用的js檔案執行個體如下:
Ext.Loader.setConfig({ enabled : true});Ext.application( { name : 'LogListApp', appFolder : 'app/logApp', autoCreateViewport : false, controllers : [ 'log.LogInfos' ], launch : function() { console.log('logListApp launch!'); Ext.create('Ext.panel.Panel', {// html: 'World!
', renderTo: 'logpanel', items:[{ xtype: 'loginfolist' }] }); }});
這此檔案中建立application,然後引用對於對應controller,以及建立頁面,通過renderTo將頁面渲染到標籤中,在ExtJs 4.1中可以採用
Ext.create的方式建立app,MyApp作為全域application執行個體變數(命名空間),但在ExtJs4.1 中將存在一個嚴重問題:新application的建立
將覆蓋以前application註冊的事件監聽,監聽失效,這將是毀滅性的。通過測試,有兩種解決辦法:
(1)、修改註冊監聽的註冊方式
原事件註冊方式可能如下:
this.control({'viewport navigatorheader button[action=login]': {click: this.login)
修改註冊方式如下:
'viewport':{ render: function(view){ view.down('navigatorheader button[action=login]').on('click',this.login); }}
將頁面事件全部註冊到render的相應函數中,這樣在ExtJs4.1版本下,各個模組的事件將依然有效。
(2)、引用ExtJs 4.2 版本
事件失效可能是ExtJs4.1版本下的一個bug,在引用4.2版本後,無需修改事件的註冊方式即可使用,但application的建立方式放生改變,
如果還是調用Ext.create('Ext.app.applicaton',{})方式無法執行個體化application ,需要改變其建立方式,在4.2版本的文檔中推薦如下方式進行建立:
Ext.application({ name: 'MyApp', launch: function() { Ext.create('Ext.container.Viewport', { items: { html: 'My App' } }); }});
那麼通過如下方法可以獲得對應的application 執行個體:
var app = MyApp.getApplication();
到此為止,就介紹完多app的下的動態載入問題。
可能存在問題:
1、如果各個模組間不存在關聯關係,沒有相互應用,多app模式下動態載入應該沒有問題。
2、如果各個模組間存在關聯關係,有相互的引用,那麼在一個模組中引用另一模組變數,由於未載入對應的檔案,將無法應用,出現錯誤,
通過Ext.require()載入部分所需檔案,這種方式也不可取,還需尋找更好的的解決辦法。