1、Extjs概要
ExtJS是一种用于在客户端创建丰富多彩的web应用程序界面,可以用来开发RIA的AJAX应用,是完全基于纯Html/CSS+JS技术的Ajax框架,提供了丰富的跨浏览器UI组件,灵活采用JSON/XML数据源开发,使得服务端表示层(VIEW)的负荷真正减轻,从而达到客户端的MVC应用。
1.1 组件模型 Component Mode
首先我们看一下组件的结构图:
组件是指Extjs中各式各样的显式控件,eVoice中目前用到的主要有Grid,FormPanel,TreePanel,menu,tabPanel,button,toolbar,Window,MessageBox, ProgressBar,LoadMask各种form表单控件等等: 其中大部分继承于组件Componet类,少量继承于Object.
Component类是整个Extjs架构中的最基础的类之一.大部分的组件对象都继承于Component
组件对象为组件的创建,渲染,事件处理,状态管理和销毁提供了统一的模型。我们构造的每一个组件都具备了由组件对象扩展出来的特性。对于EXT中的组件对象,我们可以用Ext.getCmp(组件id)的方式获取。以下是Ext2系列中组件对象的关键特性:
·
显式声明构建器链和重写 Explicit constructor chaining and overriding
组件会将一个基础构造器连同配置传入到子类中。函数initComponent用于提供制定的构造器逻辑,只要在继承链上的某一个子类实现便可,所有的组件都遵从此方式。此时的子类就可在initComponent中对其设置相关的属性,实现具体的功能。
·
可调控的渲染 Managed rendering
2.0中,每个组件都支持延时渲染(lazy rendering),又称按需渲染(on-demand rendering)。渲染的调控是自动为你完好的。即使如此,你亦可以通过的beforerender和render事件控制渲染发生、结束,达到最为灵活的自定义调控。
·
可调控的销毁 Managed destruction
每一个组件具有destroy的函数,当组件不再需要时,Ext就负责组件的结束调控,如自动垃圾回收和摧毁组件元素。当然,销毁亦提供相应的事件,如beforedestroy和destroy可按照实际的情况作出逻辑处理。
·
管理声明自动化 Automatic state management
组件内建设置和获取状态(State)的功能,只要是全局对象StateManager和一个状态
Provider都初始化好,那么多数的组件都具有自动状态管理的能力。
·
组件常规行为的统一接口 Consistent interface for basic component behavior
一般常规的行为如隐藏、显示和激活、禁用均是组件的基本特性。如需要,这些都可由子类去重写或制定。
·
由组件管理器负责的可用调配 Availability via ComponentMgr
Ext的每一个组件在创建的时候就会由组件管理器登记注册,即你可随时获取任何组件,只需调用Ext.getCmp('id')。
支持插件 Plugin support
现在任何的组件可以通过插件的形式来扩展了。插件实质是带有init方法的一种类。该方法会有一个单独的参数(类型为Ext.Component)传入到其中。插件可通过组件的plugins配置项指定。当组件创建时,如果有插件可用,组件就会调用每个插件上的init方法,传递自身的引用作为参数。每个插件之后可调用方法或响应组件的事件以实现自身的功能。
1.1.1 组件的生存周期Component Life Cycle
1.1.1.1 初始化Initialization
1.
配置项对象生效了
The config object is applied.
组件对象的构造器会把全部的配置项传入到其子类中去,并且进行下列所有的步骤。
2.
组件的底层事件创建了
The base Component events are created
这些事件由组件对象负责触发。事件有enable, disable, beforeshow, show, beforehide, hide, beforerender, render, beforedestroy, destroy
(参阅Component API文档完整的内容)。
3.
组件在组件管理器里登记了
The component is registered in ComponentMgr
initComponent这方法总是使用在子类中,就其本身而论,该方法是一个模板方法(template method),用于每个子类去现实任何所需的构造器逻辑(any
needed constructor logic)。首先会创建类,然后组件对象各层次里面的每个类都应该调用superclass.initComponent。通过该方法,就可方便地实现(implement),或重写(Override)任意一层构造器的逻辑。
4.
状态感知进行初始化(如果有的话)
State is initialized (if applicable)
如果组件是状态感知的,其状态会进行刷新。
5.
加载好插件(如果有的话)
Plugins are loaded (if applicable)
如果该组件有指定任何插件,这时便会初始化。
6.
渲染好插件(如果有的话)
The component is rendered (if applicable)
如果指定了组件的renderTo
或
applyTo配置属性,那么渲染工作就会立即开始,否则会延时渲染,即等待到显式控制显示,或是其容器告知其显示的命令。
1.
触发beforerender事件 The beforerender
event is fired
这是个可取消的事件,指定的handler可阻止组件进行渲染
2.
设置好容器 The container is set
如果没有指定一个容器,那么将使用位于DOM元素中组件的父节点作为容器。
3.
调用onRender方法 he onRender method
is called
这是子类渲染最重要的一个步骤,由于该方法是一个模板方法(template method),用于每个子类去现实任何所需的渲染逻辑(any needed render logic)。首先会创建类,然后组件对象各层次里面的每个类都应调用superclass.onRender。通过该方法,就可方便地实现(implement),或重写(Override)任意一层渲染的逻辑。
4.
组件是“隐藏”状态的
The Component is "unhidden"
默认下,许多组件是在CSS样式类如"x-hidden"设置隐藏的。如果
autoShow所配置的值为true,这时就不会有这个"hide"样式类作用在该组件上
5.
自定义的类、样式生效了 Custom class and/or style applied
一切组件的子类都支持cls和style
两种特殊的配置属性,分别用于指定用户自定义的CSS样式类和CSS规则。推荐指定cls的方法来制定组件及其各部分的可视化设置。由于该样式类会套用在组件makeup最外的一层元素,所以标准CSS规则会继承到组件下任何子元素的身上。
6.
触发render事件 The render event
is fired
这是组件通知成功渲染的一个步骤。这时,你可肯定认为组件的DOM元素已经是可用的了。如果尝试在组件之前访问组件,会报告一个不可用的错误。
7.
调用了afterRender方法 The afterRender
method is called
这是另外一个实现或重写特定所需的“后渲染”逻辑的模板方法。每个子类应调用superclass.afterRender.
8.
组件被隐藏或禁用(如果有的话) The Component is hidden and/or disabled (if applicable)
配置项hidden和disabled到这步生效
9.
所有状态感知的事件初始化(如果有的话) Any state-specific events are initialized (if applicable)
状态感知的组件可由事件声明特殊加载和保存状态。如支持,加入此类的事件。
1.1.1.3 销毁过程 Destruction
1.
触发beforedesroy事件 The beforedestroy
event is fired
这是个可取消的事件,指定的handler可阻止组件被销毁。
2.
调用了beforeDestroy方法 The beforeDestroy
method is called
这是另外一个实现或重写预定销毁逻辑的模板方法。每个子类应调用superclass.beforeDestroy。
3.
元素及其侦听器被移除 Element and its listeners are removed
若组件是渲染好的,所属的元素的事件侦听器会被移除和元素本身会从DOM那里移除。
4.
调用了onDestroy方法 The
onDestroy method is called
这是另外一个实现或重写特定所需的“后销毁”逻辑的模板方法。每个子类应调用superclass.onDestroy。注意容器类(Container
class,和一切容器的子类)提供了一个默认的onDestroy实现,自动遍历其items集合里的每一项,分别地执行子组件身上的destroy方法。
5.
在组件管理器中撤销组件对象的登记 Component is unregistered from ComponentMgr
I使得不能再从Ext.getCmp获取组件对象
6.
触发destroy事件 The destroy event
is fired
这是组件成功销毁的一个简单通知。此时组件已经DOM中已是没有的了
组件上的事件侦听器被移除 Event listeners on the Component are removed
组件本身可允许从所属的元素得到事件侦听器。如有的话,连同删除。
1.1.2 组件的X类型 XTypes
XTypes是Ext 2.0中新的概念,被认为是Ext组件的特定类型。可用的xtype摘要可在 Component类API开始的地方找到。与一般JavaScript对象用法相似,XTypes可用于查找或比较组件对象,如isXType和getXType的方法。你亦可以列出任意组件的xtpye层次表,用方法getXTypes。
然而,如何把Xtypes用于优化组件的创建和渲染过程才是XTypes发挥威力的地方。通过指定一个xtype的配置对象的写法,可隐式声明的方式创建组件,使得如果没有渲染的需要就只是一个对象而免去实例化的步骤,这时不仅渲染的动作是延时的,而且创建实际对象的这一步也是延时的,从而节省了内存和资源。在复杂的布局中,这种性能上的改进尤为明显。
//显式创建所容纳的组件
var panel = new Ext.Panel({
...
items: [
new Ext.Button({
text: 'OK'
})
]
};
//使用xtype创建
var panel = new Ext.Panel({
...
items: [{
xtype: 'button',
text: 'OK'
}]
};
第一个例子中,面板初始化的同时,按钮总是会立即被创建的。如果加入较多的组件,这种方法很可能界面的渲染速度。第二例子中,按钮直到面板真正在浏览器上显示才会被创建和渲染。
如果面板从未显示(例如有个tab一直是隐藏的),那么按钮就不会被创建,不会消耗任何资源了。
1.1.3 BoxComponent
BoxComponent 是另外一个重要的基类,该类从组件Component扩展,为任何要进行可视渲染和参与布局的组件提供了一致的、跨浏览器的箱子模型(Box Model)实现。BoxComponent负责调节大小和定位,自动处理各浏览器之间的差异,如外/内补丁、边框的问题,形成一个统一的箱子模型,以支持各种浏览器。2.0的一切容器类(container)扩展自BoxComponent