Ext這個東東太大了,能看完就已經很不錯了,完整的源碼分析就不敢說了,大概就涉及了類管理,事件管理,數據結構緩存架構,UI組件核心機制,MVC這幾個方面,只是挑着源碼看的,沒有實際完整的使用.html
公司的框架我是借鑑了EXT的結構..站在巨人的肩上咱們能夠走的更遠,內部的結構我已經改動了,組件的形式去架構不適合咱公司~sql
如圖~緩存
EXT3.4 到 4.0改動真心很大…之前是用3.4玩的,後來看到4.0又把代碼給整個重構了一次數據結構
ExtJs4.0中,涉及Class實現的主要是Ext Core , Ext.Class, Ext.Base, Ext.ClassManager 這幾個對象架構
我是用的sencha分析的,不過sencha也是基於ext的app
在ExtJs4.0中,聲明類的方式改成了 Ext.define('ClassName',{}); 這個方法實際上是Ext.ClassManager.create的一個別名,具體用法請看API吧,這裏只談談具體的實現框架
分析代碼咱先從入口開始函數
1: /**
2: * Convenient shorthand for {@link Ext.ClassManager#create}, see detailed {@link Ext.Class explanation}
3: * @member Ext
4: * @method define
5: * alert( Object.keys(Ext.ClassManager.classes) )
6: */
7: define: alias(Manager, 'create'),
alias(object, methodName):顧名思義,別名方法,將object的mothodName方法賦予給指定對象
實際上的處理函數就是定義在 Manager上的create方法了源碼分析
在這個過程當中,首先經過 Ext.Class創建原始Class,填充應用Ext.define中的配置信息,類預處理器。post
1: return new Class(data, function() {
2:
3: var postprocessors = Ext.Array.from(data.postprocessors || manager.getDefaultPostprocessors()),
4: process = function(clsName, cls, clsData) {
5: var name = postprocessors.shift();
6:
7: if (!name) {
8: manager.set(className, cls);
9:
10: if (Ext.isFunction(createdFn)) {
11: createdFn.call(cls, cls);
12: }
13:
14: return;
15: }
16:
17: this.getPostprocessor(name).call(this, clsName, cls, clsData, process);
18: };
19:
20: process.call(manager, className, this, data);
21: });
在此方法內部,會先將className添加到data,以後會new一個Class並返回,因此能夠說Ext.define出的類都是Class這個類的實例,這裏實際上是Class構造函數中的newClass類,Class實例都被Manager.classes給保存着
因而可知
ClassManager.js只是定義了ClassManager單例,它主要負責對類的管理,如類的建立與類實例化等;
真正核心的文件Class.js
1: Ext.Class = function(newClass, classData, createdFn) {
其實內部轉換作了幾件事:用本身的語言表述下
其實在外部還有後處理器,這個之後再說
具體的實現我們看源碼:
1: if (Ext.isObject(newClass)) {
2: createdFn = classData;
3: classData = newClass;
4: newClass = function() {
5: return this.constructor.apply(this, arguments);
6: };
7: }
這裏要這樣寫,其實這裏涉及到了EXT的組件模型管理機制
EXT是一套繼承體系,
我先搬運一張3.4的圖(4.0也相似)
用個人理解就是一種倒序法,簡單的說
Extjs組件架構採用的是 一套倒樹結構,父類子類之間關係是能夠經過繼承實現
仍是用個人項目爲例吧,反正這個東東我也實現了
new 一個Content對象
1:
2: //Activity行爲預建立節點,支持PPT多動畫
3: if (sqlRet.imageId) {
4: return function(rootEle, pageIndex) {
5: Xut.create('Xut.Content', {
6: 'container' : rootEle || opts.rootEle,
7: "type" : 'Content',
8: "id" : sqlRet.imageId,
9: "pageIndex" : pageIndex,
10: "isAutoPlay" : false,
11: "activityMode": true, //針對預先觸摸加載方式
12: "processstate": "preprocess"
13: })
14: }
15: }
如圖建立了一個 new Xut.Content 對象, 但是在實際構造中,代碼的開始執行確實最頂層基類Xut.Component
代碼中的實現
定義的Xut.Content 類
1: Xut.define('Xut.Content', {
2:
3: //繼承Xut.ActionBase類
4: extend: 'Xut.ActionBase',
5:
6: //PPT動畫接口
7: mixins: {
8: EffectApi: 'Xut.EffectApi'
9: },
1: //================ 熱點動做處理類=============
2: //
3: // 點擊動做行熱點基類
4: //
5: // 繼承 Xut.Behavior 行爲基類
6: //
7: // 1 獲取數據
8: // 2 配置關閉按鈕
9: //
10: //
11: Xut.define('Xut.ActionBase', {
12:
13: /* 開始定義 */
14:
15: extend: 'Xut.Behavior',
1: //================ 熱點動做處理類=============
2: //
3: // 熱點具備的基本行爲動做
4: //
5: // 1 Iscroll 導入擴展
6: //
7: // 2 關閉按鈕生成
8: //
9: // 3 建立關閉按鈕
10: //
11:
12: Xut.define('Xut.Behavior', {
13:
14: /* 開始定義 */
15:
16: extend: 'Xut.Component',
//==============UI交互動做基類=================== // // 子類 // 觸發型熱點 ActionBase // 交互型熱點 WidgetBase // Xut.define('Xut.Component', { /* 開始定義 */ mixins: { observable: 'Xut.core.Observable' }, statics: { AUTO_ID: 1000 },
執行循序
new Xut.Content –> Xut.Component –> Xut.Behavior –> Xut.ActionBase –> Xut.Content –>
開始又往上層找 Xut-ActionBase –>Xut.Behavior->Xut.ActionBase –> Xut.Component
是否是很暈。。。ext內部就是這樣玩的,爲何要這樣,之後若是有時間說下UI組件機制就知道了
迴歸正題,這樣的倒序調用,是怎麼實現的
new一個子類,直接跨過N層到了基類Xut.Component
你們回過神來
1: newClass = function() {
2: return this.constructor.apply(this, arguments);
3: };
注意這裏
return this.constructor.apply(this, arguments);
當咱們傳遞的第一個參數不是對象(函數也是對象),那麼EXT內部幫我構造了個 構造函數
這是有什麼用?第二節接着分析