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

原文链接: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是插件的入口。它允许插件在组件渲染之前插入组件并与组件进行交互。在这个阶段,插件需要将组件的引用存下来,以便插件里的其他方法可以很容易的使用它。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。在客户组件使用插件的时候,就可以很容易的通过类型来设置插件:

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内定义逻辑就更有效率,因为插件实例不会在每一个实例被创建的时候被创建。

你可能感兴趣的:(html5,plugins,sencha,webapp,mixin)