Extjs6 組件淺談


一、Component組件

一個 Ext JS 應用的界面由一個或多個叫做 組件的控件組成. 所有的組件都是 Ext.Component 類的子類,這個類可以允許參與包含實例化、渲染、自動大小和位置以及銷毀的全自動生命周期管理. Ext JS 默認提供了相當廣泛的有用的Component組件,並且任一組件能夠簡單地擴展出定制的組件.

二、組件結構

容器 是一種能夠包含別的組件的特殊類型的組件.一個典型應用是由許多以叫做組件結構的樹形結構嵌套組件構成. 容器負責其下的組件的生命周期管理 ,包含創建、渲染、自動大小 、位置和銷毀. 一個典型的應用組件結構開始於一個在頂層的 Viewport 組件,該組件包含容器和/或其下面嵌套組件.:

component_heirarchy_5

三、浮動組件

浮動 組件 使用CSS的絕對定位功能定位在document的外部, 不參與空喊的布局.一些組件像 Window(窗體) 是默認浮動的,但任意一個組件都可以使用 floating(浮動) 的配置設置成可浮動的.

上面的代碼中實例化一個 Panel(面板) 但並不渲染. 通常一個組件有一個配置好的 renderTo , 或者做為一個加入 Containe(容器)的子組件, 但在浮動組件這種情況下這二個都不需要. 浮動組件當它們的show 方法第一次調用時自動渲染到 html文檔的正文里(html body):

這里是一些其它值得注意的關於浮動組件的配置和方法:

draggable - 允許在屏幕中拖動一個浮動組件.
shadow - 自定義一個浮動組件陰影的樣子.
alignTo() - 將浮動組件與一個特定的元素對齊.
center() - 在浮動組件的窗口中居中.

四、創建和定制組件

創建或繼承

當我們創建一個新的用戶界面類時,我們必須決定這個類是需要有一個屬於自己的Component(組件) 或者是繼承那個組件.

建議繼承一個你需要的功能的一個最接近的基類. 這是因為Ext JS的自動組件生命周期管理功能提供了當一個合適的布局管理器會自動管理組件的按需渲染,自動大小的組件位置,並且自動從一個 Container(容器) 中銷毀.

寫一個新的組件類,並且以組件結構來管理位置相對於寫一個有 Ext JS 組件的新類然后不得不在框架外去渲染它要相對容易.

創建子類

類系統 使得繼承任意一部分的 Ext JS 框架變得容易.

Ext.Base 是所有 Ext JS 類的構建代碼塊, 這個類的原型和靜態成員會被所有其它類繼承.

當你確定要在Ext.Base的最底層增加新的功能時,大多數情況下開發人員要在繼承鏈中開始一些高級的處理.

下面的例子新建一個 Ext.Component 的子類:

Ext.define('My.custom.Component', {
    extend: 'Ext.Component',

    newMethod : function() {
       //...
    }
});

這個例子新建了一個類叫做, My.custom.Component, 它繼承了 Ext.Component的所有功能(方法,屬性等等),同時可以定義任意新的方法和屬性.

這個例子新建了一個類叫做, My.custom.Component, 它繼承了 Ext.Component的所有功能(方法,屬性等等),同時可以定義任意新的方法和屬性.

模版方法

Ext JS 使用 Template method pattern(模版方法模式) 代理子類,子類特定的行為.

這個意味着在組件的生命周期中在繼承鏈條中的每個類在確定的階段都會"貢獻"一些特別的邏輯片段.每個類實現了它自己的動作而允許在繼承鏈條中的其它類可以繼續貢獻它們自己的邏輯.

一個例子是這個render(渲染)函數. render 是 Componen(組件)中定義的一個函數. 它負責發起組件的生命周期中的渲染階段. render 一定不能被覆寫,但它在執行過程中會調用 onRender ,這個允許子類實現時增加一個 onRender 方法來執行子類特定的處理. 每個 onRender 方法在"貢獻"自己特殊邏輯時要先調用父類的 onRender 方法.

下圖說明了 onRender 模版方法的功能.

調用 render 方法 (這個是通過窗口的布局管理器完成). 這個方法不能覆寫並且由 Ext 的基礎類來實現. 它會調用當前子類實現的 this.onRender 方法(如果實現了). 這會調用叫父類版本等的父類版本. 最終,每個類提供了它自己的功能,控件再返回 render 函數.

Template Pattern這是一個實現了onRender 方法的組件子類示例:

Ext.define('My.custom.Component', {
    extend: 'Ext.Component',
    onRender: function() {
        this.callParent(arguments); // call the superclass onRender method

        // perform additional rendering tasks here.
    }
});



要重點關注的是很多模版方法同時有一個相關的事件. 例如這個 render 事件在組件渲染后被觸發. 創建一個子類時,然而在類的生命周期重要的階段還是必須要用模版方法來執行類的邏輯而不是事件. 事件可能被程序掛起,或者被一個處理器停止

下面的模版方法能被組件的子類實現:

initComponent 這個方法由構造器調用.用於初始化數據,建立配置和關聯事件處理器.
beforeShow 這個方法在組件顯示前調用.
onShow 允許在顯示操作時增加額外的操作.在調用父類的 onShow 后, 組件會顯示.
afterShow 這個方法在組件顯示完后被調用.
onShowComplete 這個方法在 afterShow 方法執行完成后調用.
onHide 允許在隱藏操作時增加額外的操作. 調用父類的 onHide后, 組件會隱藏.
afterHide 這個方法在組件隱藏完后調用.
onRender 允許在渲染階段執行額外的操作.
afterRender 允許在渲染完成后執行額外的操作. 在這個階段組件的元素會根據配置樣式化了,會配置好已增加的 CSS 樣式,會配置成可見和配置可用的狀態.
onEnable 允許啟用操作執行的額外操作. 在調用父類的 onEnable后,組件將啟用.
onDisable 允許禁用操作執行的額外操作. 在調用父類的 onDisable后,組件將禁用.
onAdded 允許添加新的組件到容器時執行額外操作. 在這個階段,組件在父容器的子組件列表中. 在調用父類的 onAdded 時, 將展現 ownerCt 引用, 如果配置了引用, refOwner 將被設置.
onRemoved 允許從父容器中刪除一個組件時執行的額外操作. 在這個階段,組件已經從父容器的子組件表表中刪除了, 但還沒被銷毀 (如果父容器的 autoDestroy 設為 true,那就會被銷毀, 或者這個刪除調用的第二個參數傳遞為真值). 調用父類的 onRemoved 方法后, ownerCt 和 refOwner 將不會展現.
onResize 允許改變組件大小時執行額外操作.
onPosition 允許改變組件位置時執行額外操作.
onDestroy 允許銷毀操作時執行額外操作. 在調用父類的 onDestroy 方法后, 組件將被銷毀.
beforeDestroy 這個方法在組件被銷毀前調用.
afterSetPosition 這個方法在組件位置被設置后調用.
afterComponentLayout 這個方法在組件布局完成后調用.
beforeComponentLayout 這個方法在組件布局完成前調用.
基於哪個類來繼承

選擇最好的類來繼承主要是效率問題,和基類必須提供哪些能力. 每當有一套UI組件需要渲染和管理時,有一個趨勢是總是繼承 Ext.panel.Panel .

Panel(面板) 類有很多能力:

Border(邊界)
Header(頭部)
Header tools(頭部工具)
Footer(底部)
Footer buttons(底部按鈕)
Top toolbar(頂端工具欄)
Bottom toolbar(底部工具欄)
Containing and managing child Components(包含和管理子組件)
如果不需要這些,那么使用面板(Panel)就是一種資源浪費.

Component

如果這個需要的UI組件不需要包含其它組件,就是說,如果它只是封裝一些HTML表單來實現需求,那么繼承 Ext.Component 是合適的. 例如, 下面這個類是一個包裝一個HTML image元素的組件,並允許設置和獲取 image的 src 屬性. 它同時在圖片加載時觸發一個 load(加載) 事件:

Ext.define('Ext.ux.Image', {
    extend: 'Ext.Component', // subclass Ext.Component
    alias: 'widget.managedimage', // this component will have an xtype of 'managedimage'

    autoEl: {
        tag: 'img',
        src: Ext.BLANK_IMAGE_URL,
        cls: 'my-managed-image'
    },

    // Add custom processing to the onRender phase.
    // Add a 'load' listener to the element.
    onRender: function() {
        this.autoEl = Ext.apply({}, this.initialConfig, this.autoEl);
        this.callParent(arguments);
        this.el.on('load', this.onLoad, this);
    },

    onLoad: function() {
        this.fireEvent('load', this);
    },

    setSrc: function(src) {
        if (this.rendered) {
            this.el.dom.src = src;
        } else {
            this.src = src;
        }
    },

    getSrc: function(src) {
        return this.el.dom.src || this.src;
    }
});



使用方法:

var image = Ext.create('Ext.ux.Image');

Ext.create('Ext.panel.Panel', {
    title: 'Image Panel',
    height: 200,
    renderTo: Ext.getBody(),
    items: [ image ]
});

image.on('load', function() {
    console.log('image loaded: ', image.getSrc());
});

image.setSrc('http://www.sencha.com/img/sencha-large.png');


這個例子僅僅用於演示目的 - 這個 Ext.Img 類在一個真害的應用中應該用於管理圖片..

Container(容器)

如果這個需要的UI組件需要包含其它組件,但是不需要Panel(面板) 中前面提到的任一一個特別的能力, 那么 Ext.container.Container 是需要繼承的合適的類. 在這個 Container(容器) 層面, 重要的是記住哪個 Ext.layout.container.Container 用於渲染和管理子組件.

Container(容器) 有以下附加的模版方法:

onBeforeAdd 在添加一個新的子組件前調用. 這個方法傳遞新的組件,在修改組件時可以用到,或者在以一定方式准備容器時.異常退出添加操作時返回false.
onAdd 這個方法在一個新的組件添加完成后被調用. 這個方法傳遞剛剛已添加的組件.這個方法可能用於更新任意依賴於子組件狀態的內部結構.
onRemove 這個方法在一個新的組件刪除后調用.這個方法傳遞已經刪除的組件.這個方法可能用於更新任意依賴於子組件狀態的內部結構.
beforeLayout 這個方法在容器布局(如果需要並渲染)完它的子組件前調用.
afterLayout 這個方法在容器布局(如果需要並渲染)完它的子組件后調用.
Panel(面板)

如果需要的UI組件必須有一個頭部、底部或者是工具欄,那么 Ext.panel.Panel 是個合適的類來繼承.

重要: Panel(面板)是一個Container(容器). 務必記住Layout(布局)用於渲染和管理其中的子組件.

繼承自 Ext.panel.Panel 的類通常與應用高度相關並且一般來說用於集合在一個配置的布局中的其它UI 組件 (通常是容器Containers,或者是表單字段), 並且提供意味着操作包含在其中的組件和在tbar和bbar中的控件.

Panels(面板) 有如下附加的模版方法:

afterCollapse 這個方法在面板收縮后調用.
afterExpand 這個方法在面板展開后調用
onDockedAdd 這個方法在一個加入面板的子組件停靠后調用
onDockedRemove 這個方法在一個停靠子組組從面板中刪除后調用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM