[翻译]Ext JS 教程-组件 原

一个ExtJS 应用程序是由一个或者更多个叫做组件的窗口小部件组成的。所有的组件都是Ext.Component类的子类,它允许它们参与到自动的生命周期管理中去,包括实例化、渲染、设置尺寸和位置、还有去实例化。ExtJS提供了大范围的实用组件,而且任何组件都可以很容易的被扩展,去创建一个定制的组件。

组件层次

容器是一个可以包含其他组件的特殊组件。一个典型的应用程序是由许多内嵌成树状结构,可以用组件层次代表的组件构成的。容器负责管理组件和它们的子元素的生命周期,包括创建、渲染、尺寸和位置,还有销毁。一个典型的应用程序组件层级从顶部的Viewport开始,在它里面内嵌了其他的容器或者组件。

使用容器的items配置属性,子组件被添加到容器中。这个例子使用Ext.create去实例化了两个Panel,然后把那些Panel作为子组件添加到一个Viewport中:

var childPanel1 = Ext.create('Ext.panel.Panel', {     title: 'Child Panel 1',     html: 'A Panel' });

var childPanel2 = Ext.create('Ext.panel.Panel', {     title: 'Child Panel 2',     html: 'Another Panel' });

Ext.create('Ext.container.Viewport', {     items: [ childPanel1, childPanel2 ] });

容器使用布局管理器(Layout Manager)去设置它们的子组件的尺寸和位置。要获得更多关于布局和容器的信息,请查阅布局和容器指南。

请看 Container Example 去了解这个工作的demo是如何使用items配置去向一个容器中添加组件的。

XTypes 和 懒加载(Lazy Instantiation)

每一个组件都有一个象征性的名字,这种东西称作一个xtype。比如 Ext.panel.Panel 有一个称作’panel‘的xtype。所有组件的xtype都被列在组件的API文档中。上面的例子展示了如何去添加一个已经加载好的组件到一个容器中。但是在大型的应用程序中,这不是很理想的,因为不是所有的组件需要立刻被实例化,而且根据应用程序的使用,一些组件也许从来都不会被实例化。比如一个使用Tab Panel的应用程序仅需要每一个tab被用户点击的时候,才去渲染tab里面的内容。这就是xtype被应用的地方,先允许一个容器的子元素被配置好,但是在容器没有决定它是必须的之前,它是不会被实例化的。

 下面这个示例代码使用一个Tab Panel展示了一个容器的子元素的懒加载和渲染。每一个tab有一个当tab被渲染时展示一个警告框的监听器。

Ext.create('Ext.tab.Panel', {

    renderTo: Ext.getBody(),

    height: 100,

    width: 200,

    items: [

        {

            // Explicitly define the xtype of this Component configuration.

            // This tells the Container (the tab panel in this case)

            // to instantiate a Ext.panel.Panel when it deems necessary

            xtype: 'panel',

            title: 'Tab One',

            html: 'The first tab',

            listeners: {

                render: function() {

Ext.MessageBox.alert('Rendered One', 'Tab One was rendered.');

                }

            }

        },

        {

            // this component configuration does not have an xtype since 'panel' is the default

            // xtype for all Component configurations in a Container

            title: 'Tab Two',

            html: 'The second tab',

            listeners: {

                render: function() {

Ext.MessageBox.alert('Rendered One', 'Tab Two was rendered.');

                }

            }

        }

    ]

});

这段代码运行的结果就是为第一个tab立即显示一个警告框。此现象发生的原因是第一个tab是默认活动的tab,因此它的容器Tab Panel立即初始化和渲染了它。

指导第二个tab被点击,它的警告框是不会得到显示的。这表明了在被需要以前,这个tab是不会被渲染的,因为直到这个tab被激活,render事件才被触发。

可以工作的demo见 Lazy Instantiation Example

展示和隐藏

所有的组件都内置了show和hide方法。方法隐藏组件使用的默认CSS是“display:none”,但是他可以使用hideMode配置项来修改:

var panel = Ext.create('Ext.panel.Panel', {

    renderTo: Ext.getBody(),

    title: 'Test',

    html: 'Test Panel',

    hideMode: 'visibility' // use the CSS visibility property to show and hide this component

});

panel.hide(); // hide the component

panel.show(); // show the component

浮动组件

浮动组件置身于文档流之外,使用CSS的绝对定位,不参与它们容器的布局。一些组件,比如说窗口(Window),默认是浮动的,然而任何组件都可以使用floating配置项变成浮动的。

var panel = Ext.create('Ext.panel.Panel', {

    width: 200,

    height: 100,

    floating: true, // make this panel an absolutely-positioned floating component

    title: 'Test',

    html: 'Test Panel'

});

上面的代码初始化了一个Panel,但是并没有渲染它。一般的一个组件要么有设置了一个renderTo配置,要么就作为一个容器的子组件,然而在浮动组件的情况下,两者都不是必须的。浮动组件在第第一次调用它们的show方法时自动被渲染到文档体系中。

panel.show(); // render and show the floating panel

这里有其他一些和浮动组件相关的配置和方法需要注意:

1 draggabble - 使得浮动组件可以在屏幕周围被拖动。

2 shaodow - 定制一个浮动组件的阴影。

3 alignTo() - 使浮动组件同一个特定的元素对其。

4 center() - 让浮动组件在它的容器中对其。

可以工作的浮动组件的demo见 Floating Panel Example

创建定制的组件

拼装或者扩展

当要创建一个新的用户界面(UI)类时,必须选择那个类是拥有一个组件的实体,还是扩展那个组件。

推荐做法是扩展跟所需功能最类似的基类。这是因为ExtJS提供的生命周期自动管理包含在需要时自动渲染,在被一个恰当的布局管理器自动设置组件的尺寸和位置,还有自动从容器中销毁和移除,这些功能。

创建一个组件的(继承了该组件的)新类并替换它在组件层级中的位置,比创建一个拥有一个ExtJS组件,还要在外部渲染和管理的新类,要容易。

子类

类系统(Class System)让扩展一个现有的组件变得容易。线面这个例子创建了一个Ext.Component 的子类,没有任何附加功能。

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

    extend: 'Ext.Component'

});

模板方法

ExtJS使用模板方法模式(Template method pattern)委派给子类,特定于那个子类的行为。

意思是继承链中的每一个类都也许会“贡献”针对组件的生命周期中某些方面的额外的逻辑块。每一个类都实现了它们自己的特殊行为,而且允许其它类在继承链中继续贡献它们自己的逻辑。

一个例子就是渲染(render)方法。render是Component的父类中定义的一个私有方法, AbstractComponent 负责组件生命周期中初始化和渲染方面的工作。render必须不能被重写,但是在处理过程中调用onRender允许子类的实现添加一个onRender方法去执行特定于类的处理。每一个onRender方法在“贡献”它额外的逻辑之前必须先调用它父类的onRender方法。

下面这个图描绘了onRender模板方法的功能。

render方法被调用了(这是由容器的布局管理器来完成的)。这个方法也许没有被重写,而是由Ext基类实现的。它调用了 this.onRender,this.onRender是现在的子类的实现(如果实现了的话)。调用父类的版本又调用父类的版本,等等。最后,每一个类都贡献了它的功能,并且控制流程又回到render方法。

下面的实例是一个实现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事件在组件被渲染之后被触发。然而在实现子类时,必须要使用模板方法去展现生命周期重要方法的类逻辑,而不是事件。事件也许会被延缓执行,或者被一个句柄所阻止。

下面是能够被组件的子类实现模板方法:

1 initComponent - 这个方法被构造器(constructor)调用。它被用来初始化数据,设定配置,还有附加事件处理句柄。

2 beforeShow - 这个方法在组件被显示出来之前被调用。

3 onShow - 允许显示操作有附加的行为。在调用了父类的onShow以后,组件将会是可见的。

4 afterShow - 这个方法在组件已经被显示了之后被调用。

5 onHide - 允许隐藏操作有附加的行为。在调用了父类的onHide方法之后,组件将会被隐藏。

6 afterHide - 这个方法会在组件已经隐藏之后被调用。

7 onRender - 允许渲染情形下有附加的行为。

8 afterRender - 允许渲染被完成之后又附加的行为。在这个阶段组件的元素已经根据配置定好了样式,将会添加任何配置的CSS类名的样式,同时配置了可见性和使用状态。

9 onEnable - 允许启动(enable)操作有附加的行为。在调用了父类的onEnable之后,组件将呈可用状态。

10 onDisable - 允许禁用(disable)操作有附加的行为。在调用了父类的onDisable之后,组件将呈不可用状态。

11 onAdded - 允许在一个组件被添加到容器中的时候有附加的行为。在这个阶段,组件在父容器的子条目集合之中。在调用了父类的onAdded之后,ownerCt引用将会被表现出来,而且如果配置了一个ref,refOwner将会被设置。

12 onRemoved - 允许在一个组件被从他的父容器中移除的时候有附加的行为。在这个阶段,组件将会从父容器的子条目集合中被移除,但是不会被销毁(如果父容器的autoDestroy被设置成了true,或者remove的调用调用传入了第二个肯定的参数,它将被销毁掉)。在调用了父类的onRemoved之后,ownerCt和refOwner将不会被表现出来。

13 onResize - 允许重新定义尺寸的操作有附加的行为。

14 onPosition - 允许定位的操作有附加的行为。

15 onDestroy - 允许销毁操作有附加的行为。

16 beforeDestroy - 这个方法在组件被销毁之前被调用。

17 afterSetPosition - 这个方法在组件的位置被设定之后被调用。

18 afterComponentLayout - 这个方法在组件在布局中被放置好以后被调用。

19 beforeComponentLayout - 这个方法在组件在布局中被放置好之前被调用。

扩展哪个方法

选择最好的类去扩展,主要是要考虑效率的因素,还要考虑基类必须提供哪些能力。

不论何时,一旦任何用户界面组件需要被渲染和管理,常常倾向于扩展Ext.Panel。

Panel拥有许多的能力:

1 边框(Border)

2 头部(Header)

3 头部工具(Header tools)

4 尾部(Footer)

5 尾部按钮(Footer buttons)

6 顶部工具条(Top toolbar)

7 按钮工具条(Button toolbar)

8 包含和管理子组件

如果这些能力都不是必须的,那么使用一个Panel就是在浪费资源。

组件(Component)

如果需要用户界面组件不需要包含任何其他的组件,即,如果它仅仅是封装了一些HTML形式的东西就满足了需求,那么扩展Ext.Component是合适的。比如,下面这个类就是一个包含了一个HTML图像元素,允许设置和获取图像的src属性的Component。它也会在图像被加载时触发一个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');

见于 Managed Image Example 有一个可以工作的demo。这个例子仅用于展示的目的 - Ext.Img 类则可以被用于在真实应用程序中管理图片。

容器(Container) 

如果需要的用户界面组件会包含其他的组件,但是不需要前面提到的一个Panel的能力,那Ext.container.Container就是最适合被扩展的类了。在容器几倍,记住使用了那种局部(Layout)和管理子组件是很重要的。

容器拥有下面这些附加的模板方法。

1 onBeforeAdd - 这个方法在一个新的子组件加入时被调用。它被传入了新的组件,并且也许会被用来改变这个组件,或者用某些方式对容易做一些准备工作。如果返回false,就取消添加操作。

2 onAdd - 这个方法在一个新的子组件已经加入时调用。它被传入了已经被加入的组件。这个方法也许被用来更新任何依赖子条目的状态的内部结构。

3 onRemove - 这个方法在一个新组件已经被移除之后被调用。它被传入了已经被移除的组件。这个方法也许会被用来更新任何依赖子条目的状态的内部结构。

4 beforeLayout - 这个方法在容器已经布局(必要时还有渲染)好它的子组件之前被调用。

5 afterLayout - 这个方法在容器已经布局(必要时还有渲染)好它的子组件之后被调用。

面板(Panel)

如果需要的用户界面组件必须有一个头部,尾部和工具条,那么Ext.Panel就是最适合被扩展的类。

重要的是:一个Panel是一个容器。记住那个Layout被选择用来渲染和管理子组件是很重要的。

扩展了Ext.Panel的类常常是高度应用程序相关的,并且一般被用来在一个配置好的布局中聚集其他的用户界面组件(常常是容器和表单域),还提供使用在tbar和bbar中的控制结构的方式操作所包含的组件的方法。

Panel拥有下面这些附加的模板方法:

1 afterCollapse - 这个方法在面板被收起时被调用。

2 afterExpand - 这个方法在面板被展开时被调用。

3 onDockedAdd - 这个方法在一个对接条目被加入到面板时被调用。

4 onDockedRemove - 这个方法在一个对接条目被从面板中移除时被调用。

---------------

下面是文章来源:

http://docs.sencha.com/extjs/4.2.1/#!/guide/components

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏熊二哥

Javascript快速入门(下篇)

Javascript, cheer up。 ? ? Ajax:其通过在Web页面与服务器之间建立一个额外的处理层,这个处理层就被称为Ajax引擎,它解释来自用...

21170
来自专栏数据结构笔记

Django搭建博客(七):form的使用

不过 form只提供输入框,外层的 form标签和提交按钮都需要自己添加,我们加上 form标签和提交按钮看看:

15430
来自专栏开源优测

Selenium3源码之common下action_chains.py模块分析

介绍 本文主要对action_chains.py模块的源码进行分析说明,其代码位置如图: ? 在action_chains.py模块中定义和实现了类:Actio...

32860
来自专栏葡萄城控件技术团队

ASP.NET 5系列教程 (三):view components介绍

在ASP.NET MVC 6中,view components (VCs) 功能类似于虚拟视图,但是功能更加强大。 VCs兼顾了视图和控制器的优点,你可以把VC...

22960
来自专栏林德熙的博客

win10 uwp 渲染原理 DirectComposition 渲染 例子创建工程如何写显示CompositionSurfaceBrush

本文来告诉大家一个新的技术DirectComposition,在 win7 之后(实际上是 vista),微软正在考虑一个新的渲染机制。

25010
来自专栏木子昭的博客

Redux实现组合计数器

11830
来自专栏极客编程

Cheerio,服务端的JQuery。

cheerio 是nodejs特别为服务端定制的,能够快速灵活的对JQuery核心进行实现。它工作于DOM模型上,且解析、操作、呈送都很高效。

11110
来自专栏恰童鞋骚年

ASP.Net请求处理机制初步探索之旅 - Part 4 WebForm页面生命周期

开篇:上一篇我们了解了所谓的请求处理管道,在众多的事件中微软开放了19个重要的事件给我们,我们可以注入一些自定义的业务逻辑实现应用的个性化设计。本篇,我们来看看...

11220
来自专栏Windows Community

Extensions in UWP Community Toolkit - FrameworkElement Extensions

概述 UWP Community Toolkit Extensions 中有一个为FrameworkElement 提供的扩展 - FrameworkEleme...

37780
来自专栏从零开始学自动化测试

Selenium2+python自动化25-js处理日历控件

前言 日历控件是web网站上经常会遇到的一个场景,有些输入框是可以直接输入日期的,有些不能,以我们经常抢票的12306网站为例,详细讲解如何解决日历控件...

45060

扫码关注云+社区

领取腾讯云代金券