【翻译】在Sencha应用程序中使用插件和混入

原文:Using Plugins and Mixins in Your Sencha Apps

概述

当扩展一个框架类的功能的时候,通常都会直接将新功能写入派生类,然而,如果所需的同一功能存在于多个组件,那最有效的方式就是将它定义为一个插件或混入。插件和混入都是用来将额外功能添加到其他类的类。在本文,将介绍这些类是什么,他们之间的区别,以及他们如何工作。在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)方法的类,因为该方法需要通过组件的构造函数在组件渲染之前被调用。插件可以通过组件的“pulugins”配置项引用和设置,它可以在自定义组件的原始定义的类主体内【示例】或初始化期间的配置对象内【示例】设置。

在从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‘);

混入是什么且如何去使用它?

混入也是用来为类添加功能的类。然而,它与插件的运作方式有以下的不同:

  1. 混入可以将功能添加到任何类,而插件只能用于Ext.Component类
  2. 混入声明只要在类定义内使用mixins配置项,而插件则可以被定义在类内或类的实例。
  3. 混入可以是为他们要混入功能的任何类笼统的设计的(请参阅Ext.mixin.Observable为任何类混入事件的fire/listen功能)。也就是说,它可以更明确的将应用访问限定为特定类别的类(请参阅Ext.panel.Pinnable被设计为只混入面板类)。
  4. 混入内定义的方法会被应用到目标类的原型。

当创建了一个使用混入的类的实例的时候,就可以直接在类中调用任何混入定义的方法。这些方法的内的this作用域就是类自身。【示例】有可能在混入中定义的方法会与类自身的方法同名。在这种情况,混入方法就不会被复制到目标类的原型。这事,调用该类的方法将会一直是原始定义的方法。

要调用同名的混入方法,就要从所属类中获取到混入的引用,然后再直接调用混入发昂发。在直接调用混入的方法时,它的作用域将是混入类,因而,this指向的会是混入类自身【示例】。如下面示例,如果混入有一个混入id为util,调用混入定义的destroy方法将会是这样:

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

定义自己的混入

尽管我们建议通过扩展Ext.Mixin来定义混入了,但混入也可以通过Ext.define来直接定义。通过扩展Ext.Mixin来定义的主要好处是在定义混入类的时候,允许定义“钩子”。钩子是定义在混入类的方法,会在接收类的相应的方法之前或之后自动被调用,例如,要确保混入的afterDestroy方法在类被销毁之后调用,可以使用after钩子:

mixinConfig: {
    after: {
        destroy: ‘afterDestroy‘
    }
}

如何去使用“before”、“after”、“on”和“extended”钩子的更多细节,可参阅Ext.Mixin API文档的顶部描述。

使用自己的混入

使用自己混入的首选方式是在数组中使用完整的类名。配置项mixins中的混入类会依照数组中的列出的顺序进行处理。

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

对象语法(参阅下面的选项2)提供了后向兼容,不过不建议这样,因为键名这样就不符合混入类的id定义。

获取混入类的引用

可能需要从类实例中获取类的混入的引用。这可通过所属类的实例的mixins属性,再通过混入的id来引用(例如:this.mixins.util)。建议的做法是在定义混入类的时候总是为混入类设置一个唯一的混入id。有以下三种方式来设置或确定混入类的id:

  1. 如果不是扩展于Ext.Minxn,可以在混入类的类主体内设置mixinid配置项,例如:

    mixinId: ‘util‘

    如果混入类扩展自Ext.Mixin,可以在mixinConfig配置项内设置id:

    mixinConfig: {
        id: ‘util‘
    }
  2. mixins配置项也可以被东亚为一个对象并为每一个混入类定义一个键,例如:
    mixins: {
        util: “My.utility.MixinClass”
    }
     
  3. 如果没有使用以上方法来设置id,也可以使用混入类的完整类名:
    Ext.define(‘My.utility.MixinClass‘);
    var utilMixin = owningClass.mixins[‘My.utility.MixinClass‘];

何时使用插件或混入

现在,已经了解了插件和混入,那么,在定义类的时候,何时使用插件,何时使用混入呢?由于相同的功能可能无法写入无法写入任一类的类型,这时候就要考虑如何在应用程序内使用这些功能。插件更具灵活性,因为它可以在实例上使用,且只对该实例添加开销。然而,如果功能是针对所有类的,那么在混入内定义逻辑就更有效率,因为插件示例不会在每一个实例被创建的时候被创建。

作者:Seth Lemmons
Seth Lemmons is a Senior Engineer on the Sencha Support team. He has experience in Ext JS, Sencha Touch, and software development. He lives in Boise, Idaho with his wife and ~200k other very nice people. Look for slemmon on the forums.

时间: 2024-10-07 21:35:18

【翻译】在Sencha应用程序中使用插件和混入的相关文章

在C#程序中实现插件架构

阅读提示:这篇文章将讲述如何利用C#奇妙的特性,实现插件架构,用插件(plug-ins)机制建立可扩展的解决方案. 在.NET框架下的C#语言,和其他.NET语言一样提供了很多强大的特性和机制.其中一些是全新的,而有些则是从以前的语言和平台上照搬过来的.然而,这种巧妙的结合产生了一些有趣的方法可以用来解决我们的问题.这篇文章将讲述如何利用这些奇妙的特性,用插件(plug-ins)机制建立可扩展的解决方案.后面也将提供一个简要的例子,你甚至可以用这个东西来替换那些已经在很多系统中广泛使用的独立的程

【翻译】在Ext JS 5应用程序中如何使用路由

原文:How to Use Routing in Your Ext JS 5 Apps 简介 Ext JS 5是一个重要的发布版本,它提供了许多新特性来创建丰富的.企业级的Web应用程序.MVVM和双向数据绑定为开发人员承担了大量的繁重工作.在Ext JS 5种,另一个新特性就是路由,它可以在控制器内轻松的管理历史记录.前进和后退按钮是每个浏览器都会拥有的公共用户接口,现在,使用Ext JS 5在单页面应用程序中处理导航变得相当简单了. Ext JS 5路由 在Ext JS,已经可以使用Ext.

「wxParser」小程序插件:想在小程序中快速部署富文本?这个插件让你一步搞定

上期,我们在<「微信同声传译」小程序插件:快速实现语音转文字.文本翻译.语音合成等能力>一文中介绍了「微信同声传译」小程序插件的意义.作用以及应用.而在此之前,我们还介绍过「腾讯地图」.「腾讯视频」.「医院 LBS 位置服务」插件,有兴趣了解的读者可以点击「微信极客WeGeek」公众号底部菜单「极客干货 - 小程序插件」了解. 今天我们为大家推荐的是一款富文本渲染插件「wxParser」,目前 wxParser 支持对一般的富文本内容包括标题.字体大小.对齐和列表等进行解析.同时也支持表格.代

Django 程序中添加js插件文本编辑器

第一步:在首页中添加写博客的按钮     <li>         <a href="{% url 'create_article' %}">写博客</a>     </li> 第二步:写相应的创建博客视图,编辑views.py文件 def create_article(request):     if request.method == "GET" :         return  render(request,'

在插件式应用程序中,实现对菜单,工具栏按钮的 完全解耦及状态控制

之前承诺会对 Winform IDE,WPF 客服程序的开发进行进一步的分解记录,很抱歉一直没有太多时间认真梳理. 本篇博客抽取了这两个应用程序的一个共通功能的实现方法进行说明,即在插件式应用程序中,对菜单及工具栏的控制. 对于复杂的应用程序开发,我们可能会将程序的功能进行分解,模块化,插件化:那么如何在应用程序的宿主中,向插件提供统一的菜单,工具栏注册,更新,销毁机制呢?以及如何做到UI无关的彻底解耦合? 看两个例子: 基于 Winform 的插件式应用程序: http://www.cnblo

《Entity Framework 6 Recipes》中文翻译——第九章EntityFramework在N层架构程序中的应用(五)

问题 你有一个通过WCF获取的对象,你想把它删除掉 解决方案 你有如下的模型 我们的模型代表了发票Invoice上的付款Payment.在我们的应用程序中,我们实现了一个WCF服务处理来自客户端的数据库交互.在我们的情况下,我们要使用服务删除一个支付对象实体.保持尽可能简单的解决方案,我们将建立一个WCF服务库并定义模型里面按照以下步骤: 1.新建WCF服务库程序,命名Recipe5 2.右键单击recipe5项目,并选择“添加新项.选择数据?ADO.NET实体数据模型.使用向导添加一个模型包含

Gradle 1.12用户指南翻译——第三十九章. IDEA 插件

本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://github.com/msdx/gradledoc 本文翻译所在分支: https://github.com/msdx/gradledoc/tree/1.12. 直接浏览双语版的文档请访问: http://gradledoc.qiniudn.com/1.12/userg

在Android程序中使用已有的SQLite数据库

已经将这篇文章迁移至 Code问答,你也能够到这里查看这篇文章,请多多关注我的新技术博客CodeWenDa.com 在中文搜索中,没有找到一篇比較好的关于怎样在Android应用中使用自己事先创建好的数据库的文章,于是在谷歌上找到这篇英文文章,依照它的步骤,測试成功.决定把这篇文章大致的翻译一下,想看原文的能够点击这里:http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/ .

Ubuntu再体验之【浏览器】--Chromium安装拓展程序、安装插件(360极速浏览器插件)

上次谈到了安装Chromium的Flash插件http://blog.csdn.net/rovast/article/details/38476129,有兴趣的同学可以再去看看 这次我们来看看如何安装Chrome插件(或者是360Chrome插件) [转载请注明出处:blog.csdn.net/rovast] 1.为什么要安装插件 在重新折腾上了Ubuntu Kylin 14.04后发现,谷歌被大陆屏蔽了,也就是通过在线安装插件的套路不可用了.但是在使用Windows操作系统的朋友注意到,国产的