前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[翻译]Ext JS 教程-组件 原

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

作者头像
LeoXu
发布2018-08-15 14:57:01
3.1K0
发布2018-08-15 14:57:01
举报
文章被收录于专栏:LeoXu的博客LeoXu的博客

一个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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2013/06/05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 组件层次
  • XTypes 和 懒加载(Lazy Instantiation)
  • 展示和隐藏
  • 浮动组件
  • 创建定制的组件
    • 拼装或者扩展
      • 模板方法
        • 扩展哪个方法
          • 组件(Component)
          • 容器(Container) 
          • 面板(Panel)
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档