【ExtJS 4.x学习教程】(4)组件(Components)

作者:周邦涛(Timen)

Email:[email protected]

转载请注明出处:  http://blog.csdn.net/zhoubangtao/article/details/27366477

1. 简介

一个Ext JS 应用的UI是由一个或多个叫做组件(Component)的小部件组成的。所有的组件都是Ext.Component的子类,Ext.Component可以使其子类参与自动化的声明周期管理,包括初始化、渲染、调整大小及位置和销毁。Ext JS提供了大量的直接可用的组件,并且任何组件都能够被轻松的继承从而实现定制化的组件。

2. 组件层次结构

容器是一个可以容纳其他组件的一种特殊组件。一个典型的应用程序是由多个嵌套的树状层次结构的组件组成的。容器负责管理它的子组件的生命周期,包括创建、渲染、调整大小及位置、销毁。一个典型的应用程序组件层次结构以一个Viewport在顶部开始,这个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 ]
});

容器使用容器管理器去调整它的子组件的大小和位置。更多关于布局和容器的信息请参考我的另一篇文章【ExtJS 4.x学习教程】(3)布局和容器(Layouts and Containers)

3. XType和延迟初始化

每个组件都有一个符号名叫做xtype。例如Ext.panel.Panel有一个xtype叫做‘panel’。所有组件的xtype在Ext.Component的API文档中都能找到。上边的例子显示了如何将已经初始化的组件添加到容器中,但是在一个大的应用程序中这样并不理想,由于并不是所有组件多需要立即被初始化,并且一些组件根据应用程序的使用情况可能永远不会被初始化。例如一个使用了Tab Panel的应用程序只需要用户点击了的tab的内容。这就是xtype存在的理由,它可以让容器的子元素被预先配置进去,但是知道容器决定它需要时才会被初始化。

下边的例子代码示范了延迟初始化以及使用Tab Panel渲染容器的子组件。每一个标签页有一个监听器,负责当标签页被点击时显示一个提示。

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 Panel会立即初始化它并且渲染它。

直到第二个标签页被点击它的提示框才会显示出来。这就说明这个标签页并没有被渲染直到需要它的时候,因为render方法并没有被触发直到这个标签页被激活。

例子代码可以在Ext JS 4 SDK提供的例子中找到

4. 显示和隐藏

所有的组件都有内建的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

5. 浮动组件

浮动组件使用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方法被第一次调用的时候会自动渲染到document body上:

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

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

  • draggable —— 使浮动组件能够在屏幕上拖拽
  • shadow —— 定制化浮动组件阴影的外观
  • alignTo() —— 使一个浮动组件与一个特殊元素靠齐
  • center() —— 把一个浮动组件置于它的容器中间

你可以在Ext JS 4 SDK的例子中找到浮动Panel的例子

6. 创建定制化组件

6.1 组合还是扩展

当创建一个新的UI类时,你必须确定你的类时Component的一个实例还是继承自一个组件。

这里强烈推荐继承一个和你需要功能相近的基类。这是因为Ext JS 提供的自动化生命周期管理将会被合适的布局管理器管理并且在从容器中移除时会自动销毁。

很简单就能写一个新的组件类,并且它能够在组件层次结构中占有一席之地,而不是一个包含Ext JS 组件的新类,还必须在外部对它进行渲染和管理。

6.2 子类化

类系统(见【ExtJS 4.x学习教程】(1)类系统(Class System))能够让你很简单就能继承一个已存在的组件。下边的例子创建了一个Ext.Component的子类,而没有添加任何额外的功能:

Ext.define('My.custom.Component', {
    extend: 'Ext.Component'
});

6.3 模板方法

Ext JS使用模板方法模型(具体可以参考http://en.wikipedia.org/wiki/Template_method_design_pattern)委托给子类,为对应的子类指定特定的表现。

也就是在这个层次结构链中的每一个类都可以为一个组件的生命周期的各个阶段贡献一部额外的业务逻辑。每一个类实现了他自己的特殊表现,同时还允许在这个层级结构链中的其他类继续贡献他们自己的逻辑。

render函数就是一个例子。render是一个在组件父类中定义的私有方法,AbstractComponent负责初始化组建生命周期中的渲染阶段。render不可以被重写,但是在处理过程中它调用了onRender方法使子类的实现能够添加一个onRender方法去做一些特殊的操作。每一个onRender方法添加自己的逻辑之前必须先调用它父类的onRender方法。

下边的图表描述了onRender模板方法的功能。

render方法被调用(被一个容器的布局管理器)。这个方法不可以被重写并且是由Ext的基类实现的。它调用this.onRender,而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事件在组件被渲染后触发。但是当子类化的时候使用模板函数在生命周期的重要阶段执行自己的逻辑(而不是使用事件)还是很必要的。事件可能被程序挂起,也可能被一个handler阻止。

下边是可以被组件子类实现的模板方法:

  • initComponent: 这个方法被构造器调用。它用来初始化数据、设置配置和绑定事件
  • beforeShow: 这个方法在组件显示之前被调用
  • onShow: 允许对显示操作添加额外的表现。调用父类的onShow方法后,组件就会显示出来
  • afterShow: 这个方法在组件显示之后被调用
  • onShowComplete: 这个方法在afterShow方法完成之后被调用
  • onHide: 允许对隐藏操作添加额外的行为。在调用父类的onHide方法后,组件就会被隐藏
  • afterHide: 这个方法在组件被隐藏后调用
  • onRender:允许在渲染阶段添加额外的行为
  • afterRender: 允许在渲染完成后添加额外的行为。在这个阶段,组件的元素就已经根据配置被设计好了,已经添加了任何配置的CSS类名,并且已经处在配置的可视化和有效状态。
  • onEnable: 允许对使有效(enable)操作添加额外的行为。在调用父类的onEnable方法后,组件就会变成有效状态
  • onDisable: 允许对使无效(disable)操作添加额外的行为。在调用父类的onDisable方法后,组件就会变为无效状态。
  • onAdded: 允许当一个组件被添加到容器中时添加额外行为。在这个阶段,组件已经被添加到父容器的items集合中。在调用父类的onAdded方法后,ownerCt引用就会被呈现,并且如果配置了ref,refOwner就会被设置。
  • onRemoved: 允许当一个组件被从容器中移除时添加额外行为。在这个阶段,组件已经从父容器的items集合中被移除了,但是还没有被销毁(如果父容器的autoDestroy设置为true,或者remove调用时第二个参数传入了true,这个组件就会在移除时被销毁)。在父类的onRemoved被调用之后,ownerCt和refOwner就不会呈现了。
  • onResize: 允许对大小调整(resize)操作添加额外的行为。
  • onPosition: 允许对位置调整(position)操作添加额外的行为。
  • onDestroy: 允许对销毁操作添加额外的行为,在父类的onDestroy被调用后,组件就会销毁。
  • beforeDestroy: 这个方法在组件被销毁前调用。
  • afterSetPosition: 这个方法在组件的位置被调用后调用。
  • afterComponentLayout: 这个方法在组件被布局好后调用。
  • beforeComponentLayout: 这个方法在组件被布局好前调用。

6.4 继承哪个类

选择最好的类来扩展主要是效率问题,以及考虑基类必须提供哪些能力。以前的版本总是趋向于总是继承自Ext.Panel,无论需要被渲染和管理的组件到底是什么

Panel类有很多能力:

  • Border
  • Header
  • Header tools
  • Footer
  • Footer buttons
  • Top toolbar
  • Bottom toolbar
  • 容纳和管理子组件

如果这些能力不是必须的,那使用Panel就是对资源的一种浪费。

6.4.1 组件(Component)

如果需要的UI组件不需要的容纳任何的其他组件,也就是如果它仅封装了一些必要的HTML表单等,那么继承Ext.Component比较合适。例如,下边的I类是一个封装了HTML image元素的组件,它允许设置和获取image的src属性。当image被加载完后还触发了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');

例子代码可以在Ext JS 4 SDK提供的例子中找到。这个例子只是为了展示,不要和Ext.Img类搞混了,Ext.Img类就是用来在真正的应用程序中管理图片的。

6.4.2 容器(Container)

如果你需要的UI组件需要包含其他的组件,但是不需要前边提到的Panel的功能,那么继承Ext.container.Container比较合适。在容器层,记住用那个Layout来渲染和管理子组件很重要。

容器有下边额外的模板方法:

  • onBeforeAdd: 这个方法在添加一个新的子组件之前被调用。它传入这个新子组件,它可以用来改变这个组件,或者准备容器等。如果这个方法返回false,那么添加操作就被终止。
  • onAdd: 这个在一个新的组件被添加后调用。它传入刚刚被添加的组件。这个方法可以用来更新任何依赖于items状态的内部结构。
  • onRemove: 这个方法在一个组件被移除后调用。它被传入刚刚被移除的组件。这个方法可以用来更新任何依赖于items状态的内部结构。
  • beforeLayout: 这个方法在容器已经布局好它的子组件之前被调用。
  • afterLayout: 这个方法在容器已经布局好它的子组件之后被调用。

6.4.3 面板(Panel)

如果你的UI组件必须有header,footer,或者toolbar,继承Ext.Panel会比较合适。

注意:一个Panel是一个容器。记住使用哪个Layout去渲染和管理它的子组件很重要。

继承自Ext.Panel的类通常是高度特定于应用的,并且通常使用Layout和其他的UI组件(通常是容器和form表单)一起使用,通过tbar和bbar的控制方式提供它所容纳的组件的操作方式。

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

  • afterCollapse: 这个方法在Panel被收起后调用。
  • afterExpand: 这个方法在Panel被展开后条用。
  • onDockedAdd: 这个方法在一个docked item被添加到Panel后调用。
  • onDockedRemove: 这个方法在一个docked item被从Panel移除后调用。

7. 总结

本文主要讲述了Ext JS 4的组件模型,一些常用组件,以及怎么定制一个组件。通过学习本文,你能够很好的了解Ext JS 4 组件模型的全貌,并能够新建一个组件类时,采用正确的方式。

8. 参考资料

  1. http://dev.sencha.com/deploy/ext-4.1.0-gpl/docs/index.html#!/guide/components

作者:周邦涛(Timen)

Email:[email protected]

转载请注明出处:  http://blog.csdn.net/zhoubangtao/article/details/27366477

【ExtJS 4.x学习教程】(4)组件(Components),布布扣,bubuko.com

时间: 2024-08-07 02:04:20

【ExtJS 4.x学习教程】(4)组件(Components)的相关文章

【ExtJS 4.x学习教程】(5)数据包(The Data Package)

作者:周邦涛(Timen) Email:[email protected] 转载请注明出处:  http://blog.csdn.net/zhoubangtao/article/details/27707361 1. 简介 数据包主要负责加载和保存你应用程序的所有数据,它包含41个类,但是其中三个是最重要的-- Model,Store和Ext.data.proxy.Proxy.这三个类几乎在每个应用程序都有使用,并且有很多卫星类作支持. 2. Model和Store data包的核心是Ext.d

[ExtJS学习笔记]第七节 Extjs的组件components及其模板事件方法学习

本文地址:http://blog.csdn.net/sushengmiyan/article/details/38487519 本文作者:sushengmiyan -------------------------------------------------------------资源链接----------------------------------------------------------------------- 翻译来源  Sencha Cmd官方网站: http://ww

Docker学习教程笔记整合(完整)

Docker学习教程笔记整合(完整) 本文主要是整理了DockerOne组织翻译的Flux7的Docker入门教程,通过markdown记录,方便离线学习.原文地址,http://dockone.io/article/101. 文中一些链接可能会跳转国外的网站,如果没有插件或开VPN的朋友,可以尝试修改一下Hosts文件,如何修改Hosts文件.或者使用XXNet插件,如何使用XXnet 介绍 Docker是一个新的容器化的技术,它轻巧,且易移植,号称"build once, configure

【吐血推荐】牛人收集的163个Javascript学习教程pdf电子书资源合集

不收藏是你的错^_^. 经证实,均可免费下载. 资源名称 资源大小   15天学会jQuery(完整版).pdf 274.79 KB   21天学通JavaScript(第2版)-顾宁燕扫描版.pdf 26.02 MB   5天驾驭JQuery教程.pdf 1.08 MB   ACCP软件开发初级程序员-使用Javascript增强交互效果-北大青鸟.pdf 51.70 MB   Ajax+PHP程序设计实战详解.pdf 84.29 MB   Ajax实战中文版.pdf 2.48 MB   Aj

Deep Learning五:PCA and Whitening_Exercise(斯坦福大学UFLDL深度学习教程)

前言 本文是基于Exercise:PCA and Whitening的练习. 理论知识见:UFLDL教程. 实验内容:从10张512*512自然图像中随机选取10000个12*12的图像块(patch),然后对这些patch进行99%的方差保留的PCA计算,最后对这些patch做PCA Whitening和ZCA Whitening,并进行比较. 实验步骤及结果 1.加载图像数据,得到10000个图像块为原始数据x,它是144*10000的矩阵,随机显示200个图像块,其结果如下: 2.把它的每

C++基础学习教程(八)

转载请注明出处:http://blog.csdn.net/suool/article/details/38300117 引入 在进行下一步的学习之前,我们需要厘清几个概念. RAII 首先介绍一个编程习语,"RAII"(ResourceAcquisition Is Initialization,资源获取即为初始化),他描述了利用构造函数\析构函数,并在函数返回时自动析构的机制.简言之,RAII意为构造函数获取一种资源;打开一个文件,一个网络连接,或仅仅是从某I/O流中复制一些标志.这种

Qt开发学习教程

Qt开发学习教程 一.Qt开发基础学习教程 本部分博客主要根据狄泰学院唐老师的<QT实验分析教程>创作,同时根据天山老妖自己的理解和网络搜集的资料及QT官方文档对部分知识点进行了扩展.本系列博客由天山老妖创作,发布于51CTO博客上.狄泰学院网站:http://course.dt4sw.com/ Qt开发基础学习教程目录如下: QT开发(一)--QT简介http://blog.51cto.com/9291927/1856911QT开发(二)--QT开发环境搭建http://blog.51cto

Python学习教程:WEB开发——Python WSGI协议详解

Web应用程序开发 Web应用程序的本质是什么 简单描述Web应用程序的本质,就是我们通过浏览器访问互联网上指定的网页文件展示到浏览器上. 流程如下图: 从更深层次一点的技术角度来看,由以下几个步骤: 浏览器,将要请求的内容按照HTTP协议发送服务端 服务端,根据请求内容找到指定的HTML页面 浏览器,解析请求到的HTML内容展示出来 HTTP协议的全称是HyperText Transfer Protocol(超文本传输协议) HTTP协议是我们常用的五层协议中的应用层(5层从上到下是应用层,传

java学习教程之代码块

学编程吧java学习教程之代码块发布了,欢迎通过xuebiancheng8.com来访问 java中的代码块包括下面几种: 1.普通代码块 2.构造代码块 3.静态代码块 1.普通代码块很简单看下面这个例子: public class Test{ public static void main(String args[]){ { //此处就是普通代码块,普通代码块中的代码按顺序执行 System.out.println("hello"); } } } 2.构造代码块 public cl