有关重大改变的几个要点
文章内容是对2.0新变化的综合简述。请留意Ext框架在从1.x跨越到2.0的过程中,经历了无数的细微改进、臭虫修正和其他的改动。 要逐一列出尚难为之,所以本文着重提及架构上有转换的地方,和一些全新加入的功能。本文下列的各部分将完整地解释这每一项的细节。
- 组件模型 Component Model
在1.x中就有Component和BoxComponent两个类了,但却没有深入整合到框架中去。到2.0,这两个类得到极大的改进并是一切主要组件的基础。 尽管这些类对于开发者而言一般是尽量隐藏细节,不过理解好组件生存周期这方面的基础知识有利于进一步的Ext学习。参阅详细。
- 容器模型 Container Model
有几个核心类可用于生成器件(widgets)和包含其它组件的布局。 容器Container为对象的容纳和组件的布局提供一个基础性的构成方式,对于整个Ext框架可视化必不可少。 面板Panel 从容器类继承,为用户程序提供特定功能的UI基类,属于容器结构层次中最常用的类。 窗口Window是面板的一种特殊类型,使得web应用程序如桌面式(desktop-style)那样。视见区Viewport是专为全屏幕web程序应用而设计的实用容器 。参阅详细
- 布局Layouts
1.x中的布局方式集中围绕在BorderLayout和其相关的几个类。2.0中,布局的整体架构建立在崭新的容器类、布局类上。 BorderLayout现加入到九种风格布局之中。布局类已经是全部重写设计并考虑最大的可扩展性。 布局的管理亦受益于2.0的框架,去掉一些开发者之前需要面对的复杂实现。参阅详细
- Grid
Grid组件往往都被认为是Ext的核心组件之一,在2.0的版本中同时继续演进。新版的用户界面更友好,性能更佳,功能上新加了行摘要、行归组、和一些基于插件实现如expandable rows和row numbering 等等的更多功能。参阅详细
- 模板 XTemplate
1.x的模版类处理一些简单的模版时令人满意,但对于复杂的输出任务就缺乏健壮的支持。 在2.0中,全新的XTemplate可支持子模版,数组处理,直接代码执行,逻辑判断和更多有用的功能。参阅详细
- 数据视图 DataView
1.x的模版将数据绑定到模版以生成制定的UI视图。JsonView是快速绑定JSON数据辅助类。2.0的DataView把以上两种方式作统一的处理,不同之处是它继承自BoxComponent,可更好地支持各种布局方式,新的XTemplate类为模版处理提供强大的支持。参阅详细
- 其它新组件
这些新组件包括动作(Action)、CycleButton、 Hidden (field)、 ProgressBar和TimeField。参阅详细
补充说明
- 主题
2.0支持开箱即用的主题(Theme),使用更为简化。Ext 1.x支持四套主题,但2.0减少到两套("Ext Blue" 和Gray)。 如打算自定义Ext的主题,那么Gray主题就是一份不错的蓝本,另外一些2.0 社区主题也可以提供一些思路或直接使用。 这不是API改动的一部分,但是有需要在这里提及一下。
- 突破性进展
令人遗憾,2.0的一些改动无法做到向后兼容。因为无论相关的组件还是渲染模型已经是从底层上大幅修改,许多现有的组件必须舍弃旧1.x的方式重写编写,与1.x的差别较大。 我们提供的1.x到2.0升级指南希望能协助解决现有Ext 1.x程序的升级问题。
组件模型 Component Model
组件概述
2.0的一个目标就是希望能以简单的代码块构建程序,甚至比以往更简单。 组件Component类最初在1.x引入,却没有全面整合到框架中去。在2.0中,组件所赋予的能力有长足的改进和提升,使得其成为整个架构里最为基础的一个类。组件对象为组件的创建、渲染、事件处理、状态管理和销毁提供了统一的模型,Ext下面的每一个组件具备了这些由组件对象扩展出来的特性。这是2.0组件对象的关键特性:
- 显式声明构建器链和重写 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方法,将自身的引用作为参数传入。 每个插件运行之后可调用组件的方法或响应组件的事件以实现自身的功能。
组件的生存周期Component Life Cycle
一般来说,组件的对象架构满足了“能运行(Just Works)”这一基本要求。架构在设计上已是调控好了大多数组件是怎样处理的,而且对最终开发者是透明的。 不过,若对组件对象扩展,或是有些需要制定的地方,就要利用一定的时间去实现。 深入理解组件对象的生存周期会是非常好的帮助。下面的内容就是对基于组件的每个类,一个周期内各个重要阶段作出解释:
初始化Initialization
- 配置项对象生效了
The config object is applied.
组件对象的构造器会把全部的配置项传入到其子类中去,并且进行下列所有的步骤。
- 组件的底层事件创建了
The base Component events are created
这些事件由组件对象负责触发。事件有enable, disable, beforeshow, show, beforehide, hide, beforerender, render, beforedestroy, destroy (参阅Component API文档完整的内容)。
- 组件在组件管理器里登记了
The component is registered in ComponentMgr
initComponent这方法总是使用在子类中,就其本身而论,该方法是一个模板方法(template method),用于每个子类去现实任何所需的构造器逻辑(any needed constructor logic)。首先会创建类,然后组件对象各层次里面的每个类都应该调用superclass.initComponent。通过该方法,就可方便地实现(implement),或重写(Override)任意一层构造器的逻辑。
- 状态感知进行初始化(如果有的话)
State is initialized (if applicable)
如果组件是状态感知的,其状态会进行刷新。
- 加载好插件(如果有的话)
Plugins are loaded (if applicable)
如果该组件有指定任何插件,这时便会初始化。
- 渲染好插件(如果必须的话)
The component is rendered (if applicable)
如果指定了组件的renderTo 或 applyTo配置属性,那么渲染工作就会立即开始,否则意味着延时渲染,即等待到显式控制显示,或是其容器告知其显示的命令。
渲染过程 Rendering
- 触发beforerender事件 The beforerender event is fired
这是个可取消的事件,指定的句柄(handler)可阻止组件进行渲染
- 设置好容器 The container is set
如果没有指定一个容器,那么将使用位于DOM元素中组件的父节点作为容器。
- 调用onRender方法 The onRender method is called
这是子类渲染最重要的一个步骤,由于该方法是一个模板方法(template method),用于每个子类去现实任何所需的渲染逻辑(any needed render logic)。首先会创建类,然后组件对象各层次里面的每个类都应调用superclass.onRender。通过该方法,就可方便地实现(implement),或重写(Override)任意一层渲染的逻辑。
- 组件是“隐藏”状态的 The Component is "unhidden"
默认下,许多组件是由CSS样式类如"x-hidden"设置隐藏的。如果 autoShow所配置的值为true,这时就不会有这个"hide"样式类作用在该组件上
- 自定义的类、样式生效了 Custom class and/or style applied
一切组件的子类都支持cls和style 两种特殊的配置属性,分别用于指定用户自定义的CSS样式类和CSS规则。 推荐指定cls的方法来制定组件及其各部分的可视化设置。由于该样式类会套用在组件markup最外的一层元素,所以标准CSS规则会继承到组件下任何子元素的身上。
- 触发render事件 The render event is fired
这是组件通知成功渲染的一个步骤。这时,你可肯定地认为组件的DOM元素是可用的了。如果尝试在渲染之前访问组件,会抛出一个不可用的异常。
- 调用了afterRender方法 The afterRender method is called
这是另外一个实现或重写特定所需的“后渲染”逻辑的模板方法。每个子类应调用superclass.afterRender.
- 组件被隐藏或禁用(如果有的话) The Component is hidden and/or disabled (if applicable)
配置项hidden和disabled到这步生效
- 所有状态感知的事件初始化(如果有的话) Any state-specific events are initialized (if applicable)
状态感知的组件可由事件声明特殊加载和保存状态。如支持,加入此类的事件。
销毁过程 Destruction
- 触发beforedesroy事件 The beforedestroy event is fired
这是个可取消的事件,指定的句柄(handler)可阻止组件被销毁。
- 调用了beforeDestroy方法 The beforeDestroy method is called
这是另外一个实现或重写预定销毁逻辑的模板方法。每个子类应调用superclass.beforeDestroy。
- 元素及其侦听器被移除 Element and its listeners are removed
若组件是渲染好的,所属的元素的事件侦听器和DOM树中的元素都会被移除。
- 调用了onDestroy方法 The onDestroy method is called
这是另外一个实现或重写特定所需的“后销毁”逻辑的模板方法。每个子类应调用superclass.onDestroy。注意 容器类(Container class,和一切容器的子类)提供了一个默认的onDestroy实现,自动遍历其items集合里的每一项,分别地执行子组件身上的destroy方法。
- 在组件管理器中撤销组件对象的登记 Component is unregistered from ComponentMgr
使得不能再从Ext.getCmp获取组件对象
- 触发destroy事件 The destroy event is fired
这是组件成功销毁的一个简单通知。此时组件已经DOM中已是不存在的了
- 组件上的事件侦听器被移除 Event listeners on the Component are removed
组件本身可允许从所属的元素得到事件侦听器。如有的话,连同删除。
组件的X类型 XTypes
XTypes是Ext 2.0中新的概念,被认为是Ext组件的特定类型。可用的xtype摘要可在 Component类API开始的地方找到。与一般JavaScript对象用法相似,XTypes可用于查找或比较组件对象,如isXType和getXType等的方法。其中getXTypes的方法可列出任意组件的xtpye层次表。
然而,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一直是隐藏的),那么按钮就不会被创建,不会消耗任何资源了。
BoxComponent
BoxComponent 是另外一个重要的基类,该类从组件Component扩展,为任何要进行可视渲染和参与布局的组件提供了一致的、跨浏览器的箱子模型(Box Model)实现。BoxComponent负责调节大小和定位,自动处理各浏览器之间的差异,如外/内补丁、边框的问题,形成一个统一的箱子模型,以支持各种浏览器。2.0的一切容器类(container)继承自BoxComponent。
容器模型Container Model
Ext 2.0 Component/Container Class Hierarchy
容器 Container
一个组件如果有包含其它的组件,那么,容器Container便是这个组件奠基之石。该类提供了布局方面和调节大小、嵌套组所需的逻辑,并且提供一个基础性的加入组件协调机制。容器类不应该直接使用,其目的在于为一切可视的容器组件提供一个基类。
面板 Panel
面板Panel是2.0最常用的容器,90%布局任务都离不开面板。布局里的排版元素便是面板,面板如同一张白纸,完全是空白的矩形,没有可视内容。虽然这样,面板也提供了一些预留区域, 方便加入程序所需的UI界面,包括顶部或底部的工具条、菜单栏、头部区域、底部区域和躯干区域。同时内建可展开和可收缩行为的按钮,和其它不同任务预设的按钮。面板可轻松地下降到任意的容器或布局,当中定位或渲染的逻辑全部由Ext调控,
下列是Ext 2.0面板最主要的几个子类:
Window
Window 是一种可浮动的、可最小/最大化的、可复原的、可拖动的..等此类的特殊面板。其目的在于实现一种具有桌面风格的程序界面的基类,像Ext桌面演示看到的那样。
视见区Viewport
视见区Viewport是以document.body作容器的实用类,它会与浏览器视图自适应尺寸,是全屏幕应用的基础,如浏览器大小调节、布局重新计算的问题由该类自动完成。 注意视见区Viewport除了document.body元素外不能渲染在其它的容器上,所以一个页面只能有一个视见区。
布局 Layouts
Ext 2.0 Layout Class Hierarchy
引言
2.0中最具意义的改进之一。在创建优雅的程序布局时感受到易用性或灵活性方面带来的好处。在Ext 1.x,布局的开发集中围绕在BorderLayout、Region和ContentPanel几个类。 1.x BorderLayout已经可以方便地生成UI,但要真正创建属于自己的布局,还是没有足够的支持。 创建复杂的布局通常需要手工编写一些代码应付滚动条、嵌套和某些怪癖的问题。
Ext 2.0带来了一个重写编写的、企业级应用的布局管理系统。 共有10种风格的布局管理器,分别提供构建各种可能的程序布局基础。Ext调控了布局诸如size、定位、滚动条和其他的属性方面的问题,一如既往地简单,开箱即用。在容器也可无限嵌套布局、混合其他不同风格的布局。
布局由容器内置创建,所以布局不应通过关键字new实例化这种方式直接使用。 有一种内部的机制,容器与布局能够很好地协调工作—只需配置好相关的参数,容器就会委托其负责的布局类工作。创建容器的时候,你应选定一种布局的风格以及相关的配置,这两个配置是属性layout和属性layoutConfig。 举例:
var panel = new Panel({
title: 'My Accordion',
layout: 'accordion', //在这个面板中所使用的布局样式
layoutConfig: {
animate: true //布局指定的配置项写在这里
}
// 其他Panel的选项
});
当你创建嵌套布局时,明白面板包含其他面板是很重要的,布局中的每个面板必须指定一个布局管理器。 多数情况你不需要指定布局的风格如“border”或“accordion”,较常见的是“fit”那一种,会自动调整大小自适应它的容器。 如果你不指定某个布局管理器,默认的是ContainerLayout类,不过这样很可能导致一些意料不到的情况发生,所以最好精确声明一下。
每种布局类都支持其特定的配置选项。关于布局每种配置选项可参考API文档。
布局管理器 Layout Managers
Grid
概述
2.0中的GridView有极大的改进,而Grid的UI部分,正是由GridView这个类来实现的。2.0中GridView最主要的新功能有:
- 效能的提升
GridView的底层结构和渲染代码已在2.0完整重构过,并侧重考虑了效能部分。正因性能的原因,锁定列的这一功能已经取消(参阅下一节)。
- 感观(look and feel)的改进
和新2.0的主题一起, Grid的外观控制也有新变化,使得Grid比以前更时尚和看上去更具吸引力。
- 单行归组
多个行可被归组到某一指定列,由用户重新归组亦可。
- 多行组摘要
每一组可相应的提供一个数据摘要组
- 进阶插件支持
在2.0中,新加入插件机制。GridView就是这种插件机制的一个典型例子。如范例中所示,Grid优秀的功能便是依靠几个预先做好的插件。插件RowExpander提供了展开、收缩行的功能,插件RowNumberer就提供了行中数字的支持。
列锁定的注意事项(Column Locking)
有些用户或许发现Ext 1.x中列锁定的功能,到2.0因为已经取消,并可以说以后也不再支持了。列锁定(Column locking),虽然对某些用户来说有其的用途, 但与2.0 GridView的新功能有不兼容的地方(如归组、摘要等),而且为了实现锁定会使得Grid渲染性能开销增大。 因此,1.x gridView这功能的向上升级,或打补丁,均不会由官方支持。
注意:当前有为2.0而做的用户扩展在进行中,以实现2.0的列锁定,而且看上去写得还蛮不错。更多有用资讯可论坛的帖子找到。
XTemplate
XTemplate使用了多种标签和特殊操作符支持模板,使得模板在应付复杂的数据结构时尤为健壮。这里所列出的高度概括的几项功能,欲了解完整的细节和使用方法,请参阅XTemplate API文档.
- 自动数组填充和作用域切换
- 可在子模板作用域内访问父级对象
- 可访问数组索引
- 支持数据值的简单匹配
- 自动渲染浮点型数组(不包含非对象的值)
- 基础性的条件逻辑符号if
- 可执行模板中直接写好的任意语句
- 支持模板的配置属性
- 可通过配置项对象自定义模板方法
- 可用于服务端的JavaScript模板
DataView
从表面上看,DataView跟1.x的View类非常相似。两者都支持模版数据渲染,Data store数据绑定和内建的选区模型和事件。但是, 随着2.0新架构的设计,DataView赋予了更强大的功能。 下面是这次最重要的改动:
- 继承自BoxComponent
1.x View类继承自Observable, 作为独立组件而言工作不错, 但是它并没提供内建的机制与其他组件融合的能力。而DataView就是针对这种不足作出的改进,该类从BoxComponent继承,因此如前文所述,也具备一般组件的生存周期控制。
- 发挥了XTemplate之功效
1.x View类采用了1.x本身的模版类Template 。较好满足了view自身的需求,但是难以满足一些复杂的渲染任务。DataView采用的模版类也升级到2.0的XTemplate,可轻松定制UI应付复杂的数据。
- 新增的配置选项
DataView 提供了更为灵活的-几个新选项:
- itemSelector: 必须是一个DomQuery选择符告知该类究竟如何分辨出每个item。相比1.x的做法带来更高的灵活性和更高的速度。
- simpleSelect: 一种新的选区生成模式,使得用户无须按下Shift或Ctrl键便可进行多选。
- overClass: 一个CSS的样式类,每个元素onmouseover和onmouseout时生效。
- loadingText:像其他绑定store的Ext组件一样,DataView支持标准的遮罩效果。
其它新组件
一些有趣的新组件也加入到2.0中去了。要了解这些新组件到底有什么新功能,最好还是看看API文档完整的介绍。
动作 Action
动作Action是一种从组件中抽象出来的可复用的“功能块”,即多个组件之间的同一功能都来自这个ACTION的实现。动作允许你共享句柄(handlers),配置选项和UI的更新,所有组件均支持动作的接口(主要是Toolbar,Button和 Menu组件)。 详细在API文档。
CycleButton
这是一个包含复选元素菜单的特制的SplitButton。当菜单子项每次被单击,按钮都会轮回一次状态,触发change的事件(或调用按钮的changeHandler函数,如果有的话)以激活菜单项。 FeedViewer演示程序就包含了该例子— 预览窗口地址的那个按钮就是一个SplitButton。详细在API文档。
Hidden (field)
这个便是HTML表单中隐藏域的一个简单的实现,能够以EXT FORM组件般操控。详细在API参考。
进度条 ProgressBar
1.x中的进度条是简单地内建在MessageBox类中。现在已重构为单独的器件并有进一步的改进。它支持两种不同的模式(手动和自动进度),而且LOOK and FEEL方面可轻松制定。详细在API参考。
TimeField
这是下拉列表时间选取器的简单实现。详细在API参考。