1. 程式人生 > >Ext元件渲染render的全過程詳述

Ext元件渲染render的全過程詳述

模板模式是設計模式中很重要的一個知識點,我在模式總結——模板方法這篇文章中已有總結,在面向物件設計中有著舉足輕重的地位。 

在Ext中更是發揮的淋漓盡致,為什麼這麼說呢?Ext中的元件有著很深的繼承關係,很多方法都有著重複,而且不僅 
是程式碼上的重複,更多的是流程上的重複 

比方說,Ext.Panel吧,將一個Panel顯示在瀏覽器中,其過程叫做render(渲染)。有這麼幾道工序: 
第一、觸發”beforeRender”事件 
第二、得到這個Panel的父節點(針對DOM來說),即容器,也就是供Panel入住的那個容器 
第三、設定rendered=true 
第四、呼叫onRender方法,這步是最重要的,也就是如何將元件顯示在瀏覽器上,涉及到很多流程,一會詳解 
第五、設定這個panel的css 
第六、觸發”render”事件,指的是當render完成後,觸發的事件 
第七、呼叫aferRender,這步和第四步一樣,是很重要的流程之一 
第八、看看要不要將這個panel隱藏或者失效,如果使用者設定了hidden或者disable 
第九、設定這個panel的位置,也就是doLayout,佈局 

再來,Ext.Panel的子類,Ext.TabPanel,也有這麼幾道工序: 
第一、觸發”beforeRender”事件 
第二、得到這個Panel的父節點(針對DOM來說),即容器,也就是供Panel入住的那個容器 
第三、設定rendered=true 
第四、呼叫onRender方法,這步是最重要的,也就是如何將元件顯示在瀏覽器上,涉及到很多流程,一會詳解 
第五、設定這個panel的css 
第六、觸發”render”事件,指的是當render完成後,觸發的事件 
第七、呼叫aferRender,這步和第四步一樣,是很重要的流程之一 
第八、看看要不要將這個panel隱藏或者失效,如果使用者設定了hidden或者disable 
第九、設定這個panel的位置,也就是doLayout,佈局 
第十、設定activeTab,也就是啟用哪個Tab面板 

僅僅多了第十個步驟。 

其他例子不舉了,都是僅僅在最後幾個步驟上不同而已,大家要說了,這個那是什麼模板模式,不就是最簡單的繼承嗎? 
錯了,繼承指的是屬性和方法的繼承,但現在是一個流程,一個系列的工序”繼承”,這就是模板模式了。 

我們來看,應用了模板模式後的工序 

Ext.TabPanel只有2道工序了 
第一、完成Panel渲染的工序 
第二、設定activeTab,也就是啟用哪個Tab面板 

Ext.Panel一道工序 
第一、完成Ext.Container的渲染工序 

Ext.Container有2道工序 
第一、完成BoxComponent的渲染工序 
第二、設定這個panel的位置,也就是doLayout,佈局 

Ext.BoxComponent一道工序 
第一、完成Ext.Component的渲染工序 

Ext.Component八道工序 
第一、觸發”beforeRender”事件 
第二、得到這個Panel的父節點(針對DOM來說),即容器,也就是供Panel入住的那個容器 
第三、設定rendered=true 
第四、呼叫onRender方法,這步是最重要的,也就是如何將元件顯示在瀏覽器上,涉及到很多流程,一會詳解 
第五、設定這個panel的css 
第六、觸發”render”事件,指的是當render完成後,觸發的事件 
第七、呼叫aferRender,這步和第四步一樣,是很重要的流程之一 
第八、看看要不要將這個panel隱藏或者失效,如果使用者設定了hidden或者disable

那麼在Ext是如何讓這些流程在不同類之間自由跳轉的呢?這就是大名鼎鼎的call和apply在起著重要作用了 
比如我們來看如下程式碼 
Ext.Panel.superclass.onRender.call(this, ct, position); 
什麼意思?this就是panel的意思,Ext.Panel.superclass就是Ext.Container,這句程式碼的意思就是“panel,你給我去執行container裡面的onRender方法” 
那麼在Ext.Container的onRender方法有存在著 
Ext.Container.superclass.onRender.call(this, ct, position); 
這樣的程式碼,這裡的this還是指panel,不懂看上圖,這裡所有的this統統指panel物件,記住!意思是“panel,你再給我執行container父類裡面的onRender方法” 
接著又會出現“panel,你再給我執行container父類的父類裡面的onRender方法”,一層層遞迴下去了,呵呵