談談Ext JS的組件——組件基類:Ext.Component,extext.component

來源:互聯網
上載者:User

談談Ext JS的組件——組件基類:Ext.Component,extext.component
概述

Ext.Component是所有Ext組件的基類,這在Ext.Component的API中第一句話就提到了。然後第二段說明了它包含的準系統:隱藏/顯示、啟用/禁用以及尺寸控制等。除了以上這些準系統,其實還包含了很多東西。當然,在API中不可能面面俱到,那麼,我們應當如何去理解這個組件基類呢?

Ext.Component===DIV

如果將一個Ext.Component渲染到頁面,會看到該組件會簡單的在頁面中添加一個DIV標記,就是這麼簡單。也就是說,Ext.Component就相當於一個DIV標記。那麼接下來的問題,我可以用這個做些什嗎?如果是單純的在頁面中使用一個DIV標記,我們可以讓它來顯示內容,也可以用它來與其他DIV標記構建頁面配置,總的來說,就是讓它做你想做的事情。

既然一個DIV標記可以做那麼多事情,那麼如何在Ext.Component實現你所想做的呢?

顯示內容

要在DIV內顯示內容,有兩種方式,一是直接把內容添加在DIV內進行顯示,一是找到DIV標記,再將內容添加到DIV標記內。如果你是Ext.Component的設計者,你將如何?這兩種方式呢?一般情況下,第一種方式,都會將內容寫到一個變數裡,然後用字串組合的方式將DIV標記與內容結合成一個字串再輸出, 而第二種方式基本都是使用DOM操作先擷取元素,再使用元素的innerHTML 屬性將內容寫到DIV標記內。

以上是在不使用任何javascript架構時的實現的方式,而對於Ext.Component這樣需要執行個體化後才能使用的類,如何來實現呢?如果對類設計比較熟悉的話,第一種方式的實現肯定是在類執行個體化時,將內容綁定到屬性上,然後在類內組合字元串進行輸出,第二種方式的實現基本就是提供一個方法進行操作了。因而,為了能處理這兩種方式,Ext.Component就必須提供一個屬性來存放初始化時的內容,還要提供一個方法來來處理內容的更新。在Ext.Component內實現這兩個功能的就是HTML配置項和update方法。

注意:配置項(Config options)嚴格意義上來說就是屬性,但是在Javascript中,要區分哪些屬性是允許初始化的,哪些屬性是不允許初始化的,尤其是對於唯讀屬性這樣的屬性,要區分實在不容易,如果在API中不加區分,就會增加出錯的幾率,因而在API中特意添加了配置項這一專屬名稱以示區別。

當然,對於封裝了底層DOM操作和提供了模板的架構了來說,不會真的使用那麼簡單的實現方法來實現這兩種操作。因而,不要把我說的就認為是Ext.Component的實現方式。在這裡,只要瞭解它的基本實現思路就行了。探究起來,Ext.Component實現這兩種方式是相當複雜的,複雜的地方主要在渲染流程。這個渲染流程是通過Ext.util.Renderable類實現的,它通過混入(mixins)的方式混入到了Ext.Component中。在這個Ext.util.Renderable類中,渲染HTML代碼主要是靠模板與Ext.DomHelper來實現的,有興趣的可自行研究一下,在這裡就不深入了。

樣式

對於DIV標記來說,不可缺少的一環當然是為它定義樣式或樣式類,而這個,與內容的思路是一樣的,因而也必須提供相應的配置項與方法,於是就有style和cls配置項以及addCls、removeCls和setStyle方法。至於為什麼樣式類拆分成了兩個方法,而樣式只有一個方法,具體原因我只知道樣式類在Ext JS的組件中經常需要添加或減少,使用兩個方法會更方便,其實還有第三個方法replaceCls,但至於樣式為什麼只有setStyle方法,具體原因暫時沒想到。

尺寸

控制DIV標記的尺寸,以控制DIV標記的可視範圍也是經常會使用到的,因而,這個功能是必須有的。

捲軸

當DIV標記固定了尺寸後,內容有可能會超出可視地區,這時候,你是希望顯示捲軸,讓使用者滾動查看內容,還是不顯示捲軸,直接忽略多餘的內容呢?這也是要考慮的。

隱藏/顯示

DIV的顯示和隱藏,這個也是會經常使用到的,因而也需要實現。

啟用/禁用

當使用DIV標記來實現按鈕功能的時候,這個就很有用了。

簡化樣式設定

一個DIV標記可設定的屬性很多,如果某些屬性需要經常使用到,如何簡化這些屬性的輸入呢?不可能總是使用style配置項吧?解決辦法就是直接通過配置項的方式來直接輸入,如padding、margin、border與tabIndex等。

id

說到簡化樣式設定,不得不說一下id。為DIV標記設定一個id,可以便於快速擷取DIV元素,以便進行操作。而對於組件來說了,id配置項設定的值除了昨晚元素的id外,還可以作為組件的id使用,因而具有雙重作用。但設定太多id,並不是好事,因為這很容易造成id衝突,因而要慎用。另一直可替代的方法是itemId,不過在Ext JS 5和6,有更好的reference可以使用。助於id所涉及的相關組件查詢知識,可以另開一篇文章講述。

浮動的DIV

不少網站都可以看到一些浮動的元素,如浮動的側邊欄,彈窗視窗等等,對於一個架構來說,這當然不能少,畢竟視窗、架構的資訊視窗都需要使用該功能。為了將浮動功能與準系統區分開來,便於維護,架構將浮動功能都集中到了Ext.util.Floating類,然後通過混入功能將浮動功能混入Ext.Component類。

動畫

有動畫功能的架構才夠炫,必不可少。在Ext.Component是通過混入Ext.util.Animate實現。

事件

對於事件,這個不用多說,怎麼可能缺少呢。要注意的是,在架構中,包含了兩種事件,一種是瀏覽器事件,一種是內部事件。

瀏覽器事件指的是使用者與頁面交換所產生的事件,這個是通過Ext.dom.ElementEvent實現的,在使用Ext.dom.Element進行DOM操作時候,就可以為元素繫結或解除事件。Ext.Component組件必不可少的功能就是DOM操作,因而可通過Ext.dom.Element來處理瀏覽器事件。

內部事件是指Ext JS架構內部的產生事件,如儲存(Store)載入了資料,它要通知群組件去更新顯示,而這就需要通過內部事件進行處理。瞭解清楚這個非常重要,例如,儲存已經載入資料了,但是組件並沒有更新顯示,到底哪裡出錯了呢?如果瞭解了內部事件處理流程,這個就很容易跟蹤了,例子中的處理流程就是,儲存通過讀取器(Reader)調用Ajax去伺服器載入資料,資料讀取後,代理(Proxy)會再將資料轉換為符合儲存定義格式的資料,當處理完成後,儲存發現有新的資料,就會觸發儲存的Refresh事件,在組件中,當監聽到Refresh事件的時候,說明儲存已經讀取了資料,可以更新顯示了。根據這個流程,如果資料已讀取,而沒有顯示,那說明存在的問題包括:資料讀取錯誤、資料轉換錯誤、儲存沒有觸發Refresh事件,組件沒有執行更新顯示的代碼或更新的時候出現錯誤。通過逐一排查和跟蹤分析這幾個流程就很容易找到問題所在了。

在Ext.Component中,內部事件是通過混入Ext.util.Observable類實現的。

Ext.Component與模板

在上面提及過,Ext.Component是使用模板與Ext.DomHelper來渲染元素的,也就是說,我不一定要把Ext.Component渲染為預設的DIV標記,那麼該如何來實現呢?根據上面的思路,提供一個配置項就行了,如果是使用模板,可以使用tpl配置項,如果使用Ext.DomHelper,則可繼續使用html配置項。

既然可以使用模板,那意味著可以渲染資料,那就必須預留資料介面,因而有了配置項data和setData方法。

遠程載入

如果內容是需要遠程載入後渲染的,哪怎麼辦?簡單,預留介面就行了,這就是loader配置項,它是通過Ext.ComponentLoader對象來實現遠程載入的。

我要直接操控組件產生的元素

雖然使用Ext JS,一般不需要直接操控組件產生的元素,但是確實會存在這方面的需求,因為,必須預留這方面的介面。因而,在組件中提供了getEl方法,用來返回組件所產生的元素中的最頂層的元素,有了這個元素,就可以操控元素及其子項目了,不過,要注意的是,getEl方法返回的是Ext.dom.Element對象的執行個體,而不是HTMLElement對象。

添加其他功能

經過以上一些處理,Ext.Component的功能就已經相當強大了,但可能還有有一些可能沒有考慮到的功能,而這就可以通過混入這樣的方式將新功能混入到組件中。在Ext.Component中還混入了以下功能:

  • Ext.mixin.Inheritable:為組件提供可繼承的配置屬性和配置方法。
  • Ext.util.Positionable:為組件對象提供定位介面。
  • Ext.mixin.ComponentDelegation:為組件提供委託事件。
  • Ext.mixin.Bindable:為組件提供bind配置項來串連視圖模型。
  • Ext.util.ElementContainer:為組件提供操控子項目(組件)的功能。
  • Ext.state.Stateful:為組件提供狀態功能。
  • Ext.util.Focusable:為組件提供擷取焦點的功能。
  • Ext.mixin.Accessible:為組件提供可訪問性方面的功能。
  • Ext.util.KeyboardInteractive: 為組件提供鍵盤互動功能。
小結

通過以上的分析,不知道你是否對組件有了更多的瞭解?總的來說,我就是基於這樣一種思路去瞭解和認識組件的,這種方式的主要好處就是便於記憶組件的常用配置項和方法。尤其是在需要解決一些問題或實現一些沒有提供的功能時候,可以大致知道是否能實現,如何去實現。如果大家在這方面有什麼看法或意見,請留言給我,多交流是非常有益的。

在實現了組件基類後,組件就劃分為容器類組件與非容器類組件兩條主線不斷派生出不同的組件,在下一文,將講述容器類組件。

請大家尊重作者的辛勤勞動,未經允許,請不要轉載本文,畢竟讀者的支援是作者撰寫文章的動力。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.