透視Ext JS 4類背後的機制與特點(下)

在構建 Ext.Class 之時,它會分配既細又專的處理器(processors),專門處理構成類定義的每一個部分。當前Ext缺省提供了一些處理器,包括有:mixins 多態的,配置項函數的,以及處理類擴展的都是必備的。除了缺省處理器外,還可以隨便自定義預處理器,預處理器是完全交給開發者可控的。因爲通過分解類處理單元,就可以達到了擴展性的目的,以便允許我們針對不同的場景,去制定更合適的處理器從而滿足需求(具體組裝的過程可仿照下面介紹的 static 處理器舉一反三)。

一圖勝千言,下圖即官方所出的 Ext.Class 流程圖。欲瞭解其中原理?不妨進入流程看看大致的輪廓吧!先從最左上角的前頭起前進,以此爲出發點,按箭頭方向走,走完就是從處理器的角度看的流程。至於還有一個角度,就是正下方的“Define”到“Callback”的流程,這是站在 Ext.Class 其總體上“輸入、輸出”的角度來來看。無論出於哪個角度,皆是圍繞於 Ext.Class 的內部工作流進行的。

處理器(processors)分預處理器(preprocessors)和後處理器兩種(postprocessors)。按照原作者Ed解釋道,一旦類“準備好了(ready)”就是認爲是預處理器執行完畢的階段,這時候可以把類實例化了可稱爲 “ready”;剩下的就屬於後處理器的階段——兩者就是根據這樣來區分的。典型地,後處理器負責如類簡寫方式 xtype,兼容舊版,還有向 Manager 登記之類的任務,總之都是圍繞類的後期工作,而絕對不會影響類的邏輯行爲。

Ext.Class 構造器內部中透過送入回調函數來達成處理器之間的接力,也就是說,其過程不是同步的。之所以執行處理器的每一步都是異步的(asynchronously)是爲了便於實現異步加載。排在預處理器列表中第一個便是 Loader,用於加載頁面上卻還沒有的類。我們前面的教程中已經爲大家介紹過關於Loader的用法,而其中異步加載的祕密正在於此!

運行完 Loader 之後,Ext.Class 安排 Extend 的預處理器接着進行,然後是 Mixins 多態、Config 等等,最後就是 static 處理的部分。流程如上圖所示。

預處理器其運行是完全可控的,可以隨便自定義預處理器的每一步。好比靜態的處理器,我們就詳細的看看 static 預處理器是如何寫的:

  1. Ext.Class.registerPreprocessor('statics'function(cls, data, callback) {  
  2.     if (Ext.isObject(data.statics)) {  
  3.         var statics = data.statics,  
  4.             name;  
  5.         // 原理只是簡單地拷貝一下  
  6.         for (name in statics) {  
  7.             if (statics.hasOwnProperty(name)) {  
  8.                 cls[name] = statics[name];  
  9.             }  
  10.         }  
  11.     }  
  12.     delete data.statics;  
  13.     // 已經完成好了當前預處理器,可進入下一個預處理器。  
  14.     if (callback) {  
  15.         callback.call(this, cls, data);  
  16.     }  
  17. });  
  18. // 改變數組的順序便可以改變加載預處理器的順序。  
  19. Ext.Class.setDefaultPreprocessors(['extend''mixins''config''statics']);  

上述過程其實非常直觀易明。我們登記了Ext.Class 的一個預處理器名曰 “static”,同時一定要傳入的就是這個 static 所對應的函數(第二個參數),它會傳入剛剛建立的Ext.Class,也就是那個新類,以及類的配置參數和回調函數(在預處理器執行後的回調函數),構成三個的參數傳入。由代碼可見,static 預處理器的工作量其實沒什麼,只是看看我們有否聲明瞭 static 屬性,有的話便拷貝 static  配置項對象到類對象身上。例如我們打算寫一個 getNextId 的靜態方法分配給類。寫法如下:

  1. Ext.define('MyClass', {  
  2.     statics: {  
  3.         idSeed: 1000,  
  4.         getNextId: function() {  
  5.             return this.idSeed++;  
  6.         }  
  7.     }  
  8. });  

靜態處理器產生的是靜態成員,所以直接可以在類身上調用方法,不用創建 MyClass 實例。

  1. MyClass.getNextId(); //1000  
  2. MyClass.getNextId(); //1001  
  3. MyClass.getNextId(); //1002  
  4. ... 等等  

最後一步,就是就是運行 callback 的回調函數(在上圖中有指示的)。此時此刻,您就可以在程序中使用這個類了。於是,我們就在這個回調中實例化 MyClass,如果成功也就明確了 Ext.Window 所依賴的對象均加載回來了。

  1. Ext.define('MyClass', {  
  2.     extend: 'Ext.Window'  
  3. }, function() {  
  4.    // MyClass此時此刻可用了  
  5.    var cls = new MyClass();  
  6.    cls.setTitle('Everything is ready');  
  7.    cls.show();  
  8. });  

最後一點,性能。毋庸諱言,複雜的代碼會降低性能——連主程 Ed 都承認這點。他說,雖然比較複雜,但爲了靈活性和易用性,就是算上這些代價,也是值得的。

參考資料:

轉自:http://blog.csdn.net/zhangxin09/article/details/619764
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章