1. 程式人生 > >[Sencha ExtJS & Touch] 在Sencha(Extjs/Touch)應用程序中使用plugins(插件)和mixins(混入)

[Sencha ExtJS & Touch] 在Sencha(Extjs/Touch)應用程序中使用plugins(插件)和mixins(混入)

plugins hook easy call disabled round 兼容 擴展 邏輯

原文鏈接:http://blog.csdn.net/lovelyelfpop/article/details/50853591



英文原文:Using Plugins and Mixins in Your Sencha Apps


概述

當須要擴展一個類的功能的時候,通常都會直接將新功能寫入派生類,然而,假設多個組件都須要實現某個功能,那最有效的方式就是將它定義為一個插件或Mixin。插件和Mixin都是用來將額外功能加入到其它類的類。在本文,將介紹這些類是什麽,他們之間的差別,以及他們的原理。在Sencha Fiddle。我們準備了一些演示樣例來演示這些概念。


插件是什麽且怎樣使用它?

插件是一個類,用來為 Ext.Component(或派生於 Ext.Component的類)加入或改動功能,與其它類一樣,插件要使用Ext.define方法來定義,且擴展於Ext.plugin.Abstract。

// Simple example showing how to define a plugin  
// extending form Ext.plugin.Abstract  
   
Ext.define('Fiddle.plugin.SamplePlugin', {  
    extend: 'Ext.plugin.Abstract',  
    alias: 'plugin.sampleplugin',  
   
    init: function (cmp) {  
        this.setCmp(cmp);  
    }  
});

有趣的是,它是你所定義的插件類中,必須有init(cmp)方法。由於該方法需會被組件的構造函數調用(在組件渲染之前)。插件聲明在組件的“plugins”配置項中。它能夠在類的定義內聲明【演示樣例】,或者在類的實例中【演示樣例】聲明。


在從Ext.plugin.Abstract的擴展創建插件的時候,默認會接收到init、destroy、enable和disable這4個方法。

以下來介紹一下怎樣才幹有效的使用這些方法。


init

方法init是插件的入口。它同意插件在組件渲染之前插入組件並與組件進行交互。在這個階段,插件須要將組件的引用存下來,以便插件裏的其它方法能夠非常easy的使用它。Ext.plugin.Abstract 提供了兩個訪問器方法來引用使用該插件的組件。



  • setCmp:在init(cmp)內。可使用setCmp(cmp)來把組件的引用存下來。這樣,插件內就可通過getCmp方法來得到組件的引用。

  • getCmp:該訪問器方法可被插件內其它方法使用。


方法getCmp尤為主要。由於插件與它的方法是在插件的作用域範圍內工作,也就是說,this引用的是插件自身。而不是使用插件的組件。當插件須要與它擁有者的組件的進行交互的時候,訪問方法(getter)就可在訪問客戶組件的時候派上用場。



方法init能夠在init被處理的時候設置插件邏輯,可能還須要在它擁有者組件的HTML渲染後再次設置插件邏輯。

比如,一個拖拽區域就須要在組件的HMTL被渲染到DOM後才幹被創建。

在這樣的情形,就須要監聽客戶組件的afterrender事件並在這時候設置組件的功能。【演示樣例


destroy

插件的destroy方法會在組件銷毀的時候被調用。通過插件創建的不論什麽類實例(比如。拖與放、鍵盤導航等等)須要在這時候以編程的方式顯式地被銷毀。

還有,不論什麽被設置到組件實例的屬性也必須被設置為null或刪除。【演示樣例


enable/disable


方法enable僅僅是用來將插件的disabled屬性設置為false的,而disable方法會將disabled設置為true。

在創建自己的插件時,能夠擴展該功能。還能夠在處理之前先檢測disabled狀態來決定是否使用不論什麽插件邏輯。你還能夠更進一步去使用他們。詳細取決於你的需求。【演示樣例

獲取對插件的引用


在使用的時候,因為插件中定義的方法是屬於插件而不是組件。因而,須要從組件獲取一個引用並將它返回個插件來調用它的方法。又或者,將插件的方法綁定到組件會更方便。【演示樣例

在定義插件類的時候。給插件的別名這樣一個前綴非常實用:alias:plugin.mypulugin。

在客戶組件使用插件的時候,就能夠非常easy的通過類型來設置插件:

plugins: [{  
    ptype: 'myplugin'  
}]

別名同意使用組件的findPlugin方法來搜索插件的引用。比如:

var thePlugin = owningClass.findPlugin(‘myplugin');


最後,還能夠使用組件的getPlugin方法和pluginId來引用插件。

plugins: [{  
    ptype: 'myplugin',  
    pluginId: 'myPluginId';  
}]  
   
var thePlugin = owningClass.getPlugin('myPluginId');



Mixin是什麽且怎樣去使用它?

Mixin也是用來為類加入功能的類。

然而,它與插件的運作方式有下面的不同:

  1. Mixin能夠將功能加入到不論什麽類,而插件僅僅能用於Ext.Component類

  2. Mixin僅僅能在類的定義內聲明mixins配置項,而插件則既能夠在類定義內,也能夠在類的實例中聲明。

  3. Mixin或許是為了不論什麽類設計的(請參閱Ext.mixin.Observable,它為不論什麽混入了它的類增加了事件的觸發/監聽機制)。可是它能夠更明白的混入特定的類(請參閱Ext.panel.Pinnable被設計為僅僅能混入Panel類)。

  4. Mixin內定義的方法會被應用到目標類的原型(prototype)中去。


當創建了一個使用Mixin的類的實例的時候,就能夠直接在類中調用不論什麽Mixin定義的方法。這些方法的內的this作用域就是類自身。【演示樣例】有可能在Mixin中定義的方法會與類自身的方法同名。

在這樣的情況,Mixin方法就不會被拷貝到目標類的原型。

這時。調用該類的方法將會一直是類自身的方法。

要調用同名的Mixin方法,就要從所屬類中獲取到Mixin的引用,然後再直接調用Mixin方法。在直接調用Mixin的方法時,它的作用域將是Mixin類,因而,this指向的會是Mixin類自身【演示樣例】。

如以下演示樣例,假設Mixin有一個Mixin的id為util,調用Mixin定義的destroy方法將會是這樣:

this.mixins.util.destroy.call(this);


定義自己的Mixin


雖然我們建議通過擴展Ext.Mixin來定義Mixin了,但Mixin也能夠通過Ext.define來直接定義。通過擴展Ext.Mixin來定義的主要優點是在定義Mixin類的時候,同意定義“鉤子(Hooks)”。

鉤子是定義在Mixin內的方法,會在接收類的對應的方法之前或之後自己主動被調用,比如,要確保Mixin的afterDestroy方法在類被銷毀之後調用,能夠使用after鉤子:

mixinConfig: {  
    after: {  
        destroy: 'afterDestroy'  
    }  
}

怎樣去使用“before”、“after”、“on”和“extended”鉤子的很多其它細節。可參閱Ext.Mixin API文檔的頂部描寫敘述。


使用自己的Mixin


使用自己Mixin的首選方式是在數組中使用完整的類名。配置項mixins中的Mixin類會按照數組中的列出的順序進行處理。

mixins: [  
    'My.utility.MixinClass'  // "util" is used to reference the mixin  
]

對象語法(參閱以下的選項2)提供了後向兼容,只是不建議這樣。由於鍵名這樣就不符合Mixin類的id定義。



獲取Mixin類的引用


可能須要從類實例中獲取類的Mixin的引用。這可通過所屬類的實例的mixins屬性,再通過Mixin的id來引用(比如:this.mixins.util)。建議的做法是在定義Mixin類的時候總是為Mixin類設置一個唯一的Mixinid。

有下面三種方式來設置或確定Mixin類的id:


  1. 假設不是繼承於基類Ext.Mixin。能夠在Mixin類的類主體內設置mixinid配置項,比如:

    mixinId: 'util'

    假設Mixin類繼承自Ext.Mixin,能夠在mixinConfig配置項內設置id:

    mixinConfig: {  
        id: 'util'  
    }


  2. mixins配置項也能夠被定義成一個對象。而且每個Mixin類都有一個鍵(id),比如:

    mixins: {  
        util: 'My.utility.MixinClass' 
    }
  3. 假設沒有使用以上方法來設置id,也能夠使用Mixin類的完整類名:

    Ext.define('My.utility.MixinClass');  
    var utilMixin = owningClass.mixins['My.utility.MixinClass'];



何時使用插件或Mixin


如今。已經了解了插件和Mixin。那麽。在定義類的時候,何時使用插件,何時使用Mixin呢?由於同樣的功能可能兩者都能夠實現。這時候就要考慮怎樣在應用程序內使用這些功能。

插件更具靈活性。由於它能夠在實例上使用,且僅僅對該實例加入開銷。然而,假設功能是針對全部類的,那麽在Mixin內定義邏輯就更有效率,由於插件實例不會在每個實例被創建的時候被創建。

[Sencha ExtJS & Touch] 在Sencha(Extjs/Touch)應用程序中使用plugins(插件)和mixins(混入)