Ext JS 5 手册 核心概念(三)组件

核心概念

组件

Ext JS 应用中的 UI 是由一个或多个被称为组件(Components)的构件组成的。所有组件都是Ext.Component的子类,它能自动管理组件的生命周期,如:实例化、渲染、改变大小和位置、销毁。

组件的层级

Container是一种特殊的能包含其它组件的组件。一个典型的应用是由一些树状嵌套的组件组成的,由container来负责管理组件和它们的子组件的生命周期,包括它们的:创建、渲染、改变大小和位置、销毁。一个典型应用的组件层级是由顶部的Viewport开始,它包含了其它containers和组件嵌套而成: 组件层级 子组件通过Containeritems配置属性添加到Container中。

Containers使用布局管理器来确定子组件的大小和位置。

XTypes和延时实例化

每个组件都有个被称为xtype的符号名称。比如Ext.panel.Panelxtypepanel。在大型应用中,并不是所有界面上用到的组件都需要立即被实例化,某些组件在应用中可能永远都不会使用,因此不需要被实例化。这也是使用xtype的一个原因,它能让Container的子元素先进行配置,但是直到Container决定在必要时才进行实例化。

显示和隐藏

所有组件都有内置的showhide方法。默认使用的 CSS 的display:none来隐藏组件,但是也可以通过hideMode配置属性来进行控制:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
var panel = Ext.create('Ext.panel.Panel', {
        renderTo: Ext.getBody(),
        title: 'Test',
        html: 'Test Panel',
        hideMode: 'visibility' // 使用 CSS 的 visibility 属性来控制组件的显示和隐藏
    });

    panel.hide(); // hide the component

    panel.show(); // show the component

浮动组件

浮动组件使用了 CSS 绝对定位,不参与它所属的Container的布局。像Window这样的组件默认就是浮动的,但是任何组件都可以通过floating配置项被设置为浮动组件。

通常的组件要么具有renderTo配置项,要么被添加为某个Container的子组件,但是浮动组件不需要这样。浮动组件在初次调用show方法时被自动渲染到body中。

其它几个与浮动组件相关的配置项和方法:

  • draggable 允许组件在屏幕上拖动
  • shadow 自定义浮动组件的阴影效果
  • alignTo() 将浮动组件对齐到某个特定的元素
  • center() 将浮动组件定位到Container的中心位置

创建自定义组件

组合或扩展

创建新的 UI 类时,可以使用组合或继承Component的方法。

推荐继承功能性最接近的类。因为它能使用 Ext JS 提供的自动化生命周期管理。

子类化

Ext.Base是所有类型的基础,这个类的原型和静态成员被所有其它类所继承。

可以向这个Ext.Base中添加低层次的功能。

模板方法

Ext JS 使用模板方法模式将行为委派给子类,行为只对子类型有效。

继承链中的每个类都可以向组件的生命周期的某个阶段“贡献”出额外的逻辑代码。每个类都实现了特定的行为并允许继承链中的其它类“贡献”它们的逻辑。

render方法为例,它是Component中定义的方法。它的职责是启动组件的渲染阶段。render不允许被覆盖,但它会调用onRender来允许子类添加它们自己的处理过程。每个子类在onRender方法中必须先调用它们的父类的onRender方法。

下面的图描述了onRender模板方法的运行机制。

Render方法被调用时(通常由Container的布局管理器)。这个方法可能没有被覆盖,而是继承自Ext.base类。它调用当前的子类中实现的this.onRender(如果有)。这将调用父类型中的方法。最后,每个类中的功能都调用到了,控制权返回到render函数 模板方法调用机制 以下是一个Component的子类实现的onRender方法:

1
2
3
4
5
6
7
8
Ext.define('My.custom.Component', {
    extend: 'Ext.Component',
    onRender: function() {
        this.callParent(arguments); // call the superclass onRender method

        // perform additional rendering tasks here.
    }
});

需要注意的是很多模板方法也有对应的事件。比如render事件,它在组件被渲染之后触发。当进行子类化时,必须使用模板方法在生命周期的重要阶段执行它的逻辑,而不使用事件。事件可以以编程的方式挂起,或被事件处理器停止。

以下是Component的子类型可以实现的模板方法:

  • initComponent 这个方法由构造器调用。它用于初始化数据,设置配置项和添加事件处理器。
  • beforeShow 这个方法在组件显示前被调用。
  • onShow 在显示操作时添加行为。在调用父类的onShow之后,组件将被显示。
  • afterShow 这个方法在组件显示后被调用。
  • onShowComplete 这个方法在调用调用完afterShow之后执行。
  • onHide 在隐藏操作时添加行为。在调用你类的onHide之后,组件将被隐藏。
  • onRender 在渲染阶段添加行为。
  • afterRender 在渲染完成之后添加行为。在这个阶段组件的 DOM 元素将按配置被设置样式,会具有任何配置了的 CSS 类名称,并且会被按配置设置为显示和启用状态。
  • onEnable 在启用操作时添加行为。在调用父类的onEnable之后,组件被启用。
  • onDisable 在禁用操作时添加行为。在调用父类的onDisable之后,组件被禁用。
  • onAdded 在组件被添加到Container时添加行为。在这个阶段,组件已经存在于父Container的子项集合中。在调用父类的onAdded之后,ownerCt引用将会存在,如果配置了refrefOwner将被设置。
  • onRemoved 在组件从Container中移除时添加行为。在这个阶段,组件已经被从父Container中移出,但是还未被销毁(它将在父ContainerautoDestroy被设置为true或调用remove时传递的第二个参数为true时被销毁)。在调用完父类的onRemoved之后,ownerCtrefOwner将不再存在。
  • onResize 在改变大小时添加行为。
  • onPosition 在改变位置时添加行为。
  • onDestroy 在销毁操作时添加行为。在调用父类的onDestroy后,组件将被销毁。
  • beforeDestroy 在组件被销毁前执行。
  • afterSetPosition 在组件的位置被设置之后执行。
  • afterComponentLayout 在组件被布局之后执行。
  • beforeComponentLayout 在组件被布局之前执行。
继承哪个类

无论 UI 组件是否需要被渲染和管理,总是倾向于继承Ext.panel.Panel

Panel类有非常多的功能:

  • 边框
  • 头部
  • 头部工具条
  • 底部
  • 底部按钮
  • 顶部工具条
  • 底部工具条
  • 容纳和管理子组件
Component

如果需要的 UI 组件不需要包含其它组件,而只是一些 HTML,则继承Ext.Component也是合适的。

Container

如果需要的 UI 组件要能包含其它的组件,但是不需要Panel的其它功能,则可以继承Ext.container.Container。需要记住Ext.layout.container.Container用于渲染和管理子组件。

Container有下列额外的模板方法:

  • onBeforeAdd 这个方法在添加了新的子组件时被调用。它会传递这个新的组件,以便修改这个组件,或以其它方式准备Container。返回false时将中止添加操作。
  • onAdd 这个方法在添加了新的组件之后执行。它将会传递这个新添加的组件。这个方法可以用于根据子组件的状态更新内部结构。
  • onRemove 在子组件被删除时被调用。它将传递要被删除的组件。这个方法可以用于根据子组件的状态更新内部结构。
  • beforeLayout 这个方法在Container对它的子组件进布局(和渲染)之前执行。
  • afterLayout 这个方法在Container对它的子组件进行而已(和渲染)之后执行。
Panel

如果需要的 UI 组件需要头、尾或工具栏时,应该继承Ext.panel.Panel

重点:Panel是一个ContainerLayout是用于渲染和管理子组件的。

继承Ext.panel.Panel是应用中经常使用的,用于将 UI 组件进行布局的类,并能使用tbarbbar来提供操作。

Panel有以下额外的模板方法:

  • afterCollapse 这个方法在Panel收缩时被调用。
  • afterExpand 这个方法在Panel展开时被调用。
  • onDockedAdd 这个方法在Docked项添加到Panel上后被调用。
  • onDockedRemove 这个方法在Docked项从Panel上删除后被调用。