【翻译】要理解Ext JS 5小工具

原版的:Understanding Widgets in Ext JS 5

在Ext JS 5,引入了新的“widgetcolumn”,支持在网格的单元格中放置组件。

同一时候,还在Ext JS 5引入了一种新的被称为“小部件”的轻量级组件。

在Ext JS 5中,已包括了几个小部件,在本文将告诉你怎样轻松的去打造自己的小部件。

为了说明当中的关键概念。在文中将创建一个简单的名为“ratings”的例如以下图所看到的的小部件:

入门

与经常使用的从Ext.Component派生的组件不同。小部件派生于新的基类Ext.Widget。并且,Ext.Widget的派生类差点儿全然是由配置系统来定义的(后面会谈到)。

Ext.Widget还要定义了DOM元素是怎样产生且怎样与DOM事件连接的。

渲染

对于小部件,首先要考虑的是怎样去定义它的DOM树,典型的方式是例如以下面代码哪样在类指定element属性来实现:

Ext.define(‘Ext.ux.rating.Picker‘, {
    extend: ‘Ext.Widget‘,

    //...

    element: {
        cls: ‘ux-rating-picker‘,
        reference: ‘element‘,

        children: [{
            reference: ‘innerEl‘,
            cls: ‘ux-rating-picker-inner‘,

            listeners: {
                click: ‘onClick‘,
                mousemove: ‘onMouseMove‘,
                mouseenter: ‘onMouseEnter‘,
                mouseleave: ‘onMouseLeave‘
            },

            children: [{
                reference: ‘valueEl‘,
                cls: ‘ux-rating-picker-value‘
            },{
                reference: ‘trackerEl‘,
                cls: ‘ux-rating-picker-tracker‘
            }]
        }]
    },

    //...
});

对象element是基于Ext.dom.Helper规范来创建DOM元素的,基本的新增功能是reference和listeners属性。

这些名字在视图控制器上已经司空见惯了。而他们在小部件上所要做的事情也相似。在Ext.Widget,全部元素的reference属性都会以名称作为属性值被缓存在小部件实例中(比如:element、innerEl等等)。

事件

在上述的element中。在innerEl对象中还定义了listeners对象。

这些监听会附加到从规范块产生的元素上。方法会依据名称在小部件类中寻找。比如:

Ext.define(‘Ext.ux.rating.Picker‘, {
    extend: ‘Ext.Widget‘,

    //...

    onClick: function (event) {
        var value = this.valueFromEvent(event);
        this.setValue(value);
    },

    onMouseEnter: function () {
        this.element.addCls(this.overCls);
    },

    onMouseLeave: function () {
        this.element.removeCls(this.overCls);
    },

    onMouseMove: function (event) {
        var value = this.valueFromEvent(event);
        this.setTrackingValue(value);
    },
 

尽管这看起来有点相似编写传统的组件类。但比較明显的是缺少初始化代码和清理代码。Ext.Widget的构造函数会处理元素的创建、跟踪他们的引用并设置监听。

除了这些动作(和对应的销毁方法)外,Ext.Widget再没有额外的生命周期或相关开销。

作为替代方法,派生类可通过配置系统提供的config属性来定义它的行为。对于那些不了解配置系统的,下面将简介一下。

配置系统101

Ext JS的核心理念之中的一个就是“配置(config)”属性的概念。

他们从一開始就是Ext JS的一部分,而不单是在Ext JS 5(或Sencha Touch 2.x)才有。框架已经将这些属性的机制规范化。常见的配置是这样声明的:

Ext.define(‘Ext.ux.rating.Picker‘, {
    //...
    config: {
        family: ‘monospace‘
    }
    //...
});

上述声明等同于下面的手写代码:

Ext.define(‘Ext.ux.rating.Picker‘, {
    //...

    getFamily: function () {
        return this._family;
    },

    setFamily: function (newValue) {
        var oldValue = this._family;

        if (this.applyTitle) {
            newValue = this.applyFamily(newValue, oldValue); // #1
            if (newValue === undefined) {
                return this;
            }
        }

        if (newValue !== oldValue) {
            this._family = newValue;

            if (this.updateFamily) {
                this.updateFamily(newValue, oldValue); // #2
            }
        }

        return this;
    },

    //...
});

这样的自己主动化处理主要有下面显著的长处:

  • 清晰:更少的代码。类更易读
  • 一致性:全部配置都有同样的行为
  • 灵活性:当实现正确时,配置属性能够在不论什么时候改变,而不是仅仅能在创建时改变(在Ext JS中很多旧的配置属性的常见的局限)

开发者能够为不论什么属性提供两个关键的。也是可选的方法。如family,则为applyFamily和updateFamily(上面代码中的#1和#2处)。

这些方法差点儿总是会比重写而不是get或set方法。

应用方法(applier)

应用方法执行开发者去将接收值转换为存储的实际值。对于很多应用方法来说,这可能意味着基于接收到的配置对象来创建一些类的实例,又或者可能是应用方法在有一个地方标准化内部表示形式以避免在全部使用该属性的地方对它进行检查。

更新方法(updater)

当配置属性的值发生了改变,就会调用更新方法。更新方法的作用就是将旧值转换为新值。

initConfig——把它捎上

最后要说的是,要将一个类增加熬配置系统中。就必须在某个点调用initConfig方法。在Ext.Widget,它会在构造函数中执行。方法initConfig会接收config对象并会处理它的每个属性以便这些在类中的声明能适当的去调用set、apply和update方法。

该方法还提供了一个“适时(just in time)”的设置机制来解决配置属性之间的顺序问题,比如,假设一个配置属性的更新方法须要还有一个配置属性的值。它就要调用还有一个配置属性的get方法。在底层。initConfig会依据所请求属性之前返回的结果正确依照顺序调用set/apply/update方法。

使用cachedConfig进行优化

对于小部件,在有些时候须要很多配置来维护DOM。

因为不论什么给定的小部件实例不太可能重写全部的默认配置值。假设能够将这些要处理的默认值缓存起来。是最理想只是了。对于这些配置,能够对类进行下面改动:

Ext.define(‘Ext.panel.Panel‘, {
    //...
    cachedConfig: {
        family: ‘monospace‘
    }
    //...
});

在大多数情况。这些配置与经常使用的配置是一样的。只是,在缓存这些配置的时候。配置系统会在类创建第一个实例的时候执行一些额外处理。

第一次实例化

在第一个实例的配置对象处理之前,配置系统仅仅会从类的默认值进行初始化。该处理会调用各种apply和update方法。这反过来会依据元素规范更新DOM元素最初的生成。

考虑下family配置,它带有下面更新方法:

updateFamily: function (family) {
    this.element.setStyle(‘fontFamily‘, "‘" + family + "‘");
},

全部的更新方法有助于为小部件设置DOM的默认状态。

一旦配置被设置为他们的默认值。就会调用afterCachedConfig方法。该方法,仅仅会在第一次实例化的时候才起作用。Ext.Widget会深度克隆所得到的DOM树(使用cloneNode(true)DOM API)。

第二个实例(及以后)

在创建同样的小部件类的还有一个实例的时候。Ext.Widget会使用缓存的DOM树克隆并深度克隆它来创建性能的小部件DOM树。这可避免又一次处理元素规范和执行默认值的更新方法的开销。假设配置的更新方法书写正确,该处理过程非常大程度上是透明的。

当然。Ext.Widget在复制DOM树后,还有一些工作须要去做,比如检索元素的引用、封装监听并将不论什么非默认值的配置属性设置到实例。

只是,这时的开销就直接与赋予实例的配置值的数量有关而不是类的配置属性了。

重用,循环

下面来研究下怎样创建并初始化一个单一的小部件,有几个重要的概念是与在widgetcolumn中使用小部件有关的。

因为限制创建的实例一直是重点,因而缓冲渲染是关键。使用该方法。网格将渲染比记录少得多的小部件。并须要在行移出滚动区域“之后”且新行渲染“之前”循环使用。

当这些转变发生时,widgetcolumn将会将DOM中的小部件移动到新行,通过dataIndex从对应的记录读取字段数据并调用小部件的setConfig来设置它的defaultBind属性,这将会调用apply和update方法,因而,仅仅要编码正确。小部件如今就能够被又一次配置来显示新的字段值。

在当前演示样例的小部件,因为它仅仅表示一个可编辑的值,因而须要在updateValue方法做检查以了解小部件是否已经使用在网格单元格:

column = me.getWidgetColumn && me.getWidgetColumn();
record = column && me.getWidgetRecord && me.getWidgetRecord();
if (record && column.dataIndex) {
    record.set(column.dataIndex, value);
}

方法getWidgetColumn和getWidgetRecord通过widgetcolumn被放置到小部件上,因此它知道它在网格中的上下文(context)。

小结

尽管大部分小部件的讨论与网格有关。但小部件也可用于传统部件的不论什么地方。

评分小部件作为迷你小部件引入Ext JS 5已经成为事实。

下面是演示样例应用程序的主面板截图。显示了它的items数组中的4个实例。

假设对上面的看起来非常熟悉,预计是你已经了解了Sencha Touch的模式。尽管这些是Ext JS 5的扩展,Ext.Widget本质上是最初在Sencha Touch中的Ext.AbstractComponent的最后版本号。

因此。你会使用小部件来取代组件?在很多方面,编写小部件是比编写组件简单。假设纯粹仅仅使用CSS来处理布局需求,尤其如此。

另外,随着我们继续将Sencha移动和桌面框架结合在一起。小部件在未来将会有跨界的可能。

能够在这里找到新的小部件的完整代码演示样例。享受它并让我们知道你的想法。

作者:Don Griffin
Don Griffin is a member of the Ext JS core team. He was an Ext JS user for 2 years before joining Sencha and has over 20 years of software engineering experience on a broad range of platforms. His experience includes designing web application front-ends and back-ends, native GUI applications, network protocols and device drivers. Don’s passion is to build world class products that people love to use.

时间: 2024-11-07 11:16:44

【翻译】要理解Ext JS 5小工具的相关文章

【翻译】使用Ext JS设计响应式应用程序

原文:Designing Responsive Applications with Ext JS 在当今这个时代,用户都希望Web应用程序无论在形状还是大小上,既能在桌面电脑,也能在移动设备上使用.使应用程序能适应不同的需求渐成趋势.幸运的是,Ext JS 5提供了所有支持应用程序以符合任何屏幕尺寸.形状和方向的工具. responsiveConfig概述 要让Ext JS 5支持新的平板电脑,需要使用"responsiveConfig",一个强大的新功能,可以让应用程序根据屏幕大小和

【翻译】在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.

【翻译】在Ext JS和Sencha Touch中创建自定义布局

原文:Creating Custom Layouts in Ext JS and Sencha Touch 布局系统是Sencha框架中最强大和最独特的一部分.布局会处理应用程序中每个组件的大小和位置,因而,不需要手动去管理那些碎片.Ext JS与Sencha Touch的布局类有许多相似之处,最近在 Ivan Jouikov的这篇博文中对他们进行了详细的分析. 虽然是这样,但很多Ext JS和Sencha Touch开发人员可能永远都不会去了解布局系统的机制原理.Sencha框架已经提供了最常

【翻译】在Ext JS 5种使用ViewControllers

原文:Using ViewControllers in Ext JS 5 简介 在Ext JS 5中,在应用程序架构方面提供了一些令人兴奋的改进,如添加了ViewModels.MVVM以及viewControllers来加强MVC应用程序.最重要的是,这些选择并不互斥,因此,可以采用增量的方式来介绍这些功能,又或者将他们混合在一起. 回顾控制器 在Ext JS 4,控制器就是一个从Ext.app.Controller的派生的类.这些控制器会使用类似CSS选择器(称为组件查询)来查找组件并对他们的

【翻译】了解Ext JS 5的小部件

原文:Understanding Widgets in Ext JS 5 在Ext JS 5,引入了新的"widgetcolumn",支持在网格的单元格中放置组件.同时,还在Ext JS 5引入了一种新的被称为"小部件"的轻量级组件.在Ext JS 5中,已包含了几个小部件,在本文将告诉你如何轻松的去打造自己的小部件. 为了说明其中的关键概念,在文中将创建一个简单的名为"ratings"的如下图所示的小部件: 入门 与常用的从Ext.Compon

【翻译】探究Ext JS 5和Sencha Touch的布局系统

原文:Exploring the Layout System in Ext JS 5 and Sencha Touch 布局系统是Sencha框架中最强大和最有特色的一个部分. 布局要处理应用程序中每一个组件的尺寸和位置.在Ext JS和Sencha Touch直接有很多相似之处.尤其是如今Ext JS 5開始支持平板更是如此.以下让我们来探讨一下布局系统是怎样跨域Sencha框架进行工作的. 布局简史 最主要的HTML一直都缺乏一个严格定义的布局系统. 很多年来,因为CSS实现的差距.开发跨浏

【翻译】在Ext JS应用程序中构建可维护的控制器

原文:Building Maintainable Controllers in Ext JS Apps 你好You Had Me 你是Tearing Me Apart 模板We Dont Need to be aware of No Stinkin的模板 What Weve Got Here是一个失败的沟通者 聪明的视图是重点且易于维护和测试 在eMortgage Logic公司,2011年底开始使用Ext JS 4.当时,还不知道如何正确编写Ext JS应用程序,但最后还是掌握了如何让应用程序

使用node.js,实现简单的JS合并小工具

最近在学node.js,之前由于实验室项目需要,用C#写了个JS代码压缩合并的小插件,想想正好可以用node重构,来练练手.本人node新手,大神止步O(∩_∩)O 上代码: /*符合CommonJs规范*/ var writePath = 'min.js',/*默认输出到本目录min.js文件里*/ fs = require('fs'), r1 = /^(.+)$/mg,/*分行*/ r2 = /\s{2,}/g,/*去空格*/ r3 = /([^\\])\/\/.*/g,/*去行注释*/ r

【翻译】Ext JS 5的平板支持

原文:Ext JS 5 Tablet Support Ext JS已被公认为桌面Web应用程序的领先框架.自从平板开始在全球挑战PC的销售,无论是个人还是企业,电脑横向的应用已经产生急剧的变化.Sencha意识到了这种变化,并推出了包含新功能和进行优化了的Ext JS 5. Ext JS从Sencha Touch 2学到了一些新把戏.多年最好的移动Web应用程序框架经验的沉淀要应对现代平板电脑上的桌面显示,那是卓卓有余的.通过类系统.事件管理.窗口小部件和新的部署选项就可以了解到这些更新. 除了