从八月开始不用加班了,应该会有比较多的时间来把这些文档翻译完了.之所以翻译这些文档,是因为我觉得这几篇是比较重要的(我翻译的顺序是按我自己认为要看的顺序翻译的),自己在看,就顺便翻译了(其实英语很差,google翻译不停的查的...),加强一下记忆,怕以后又忘记了.英语好的还是看原文吧,不要被我误导了:官方原文
用Extjs4一个月了,中间遇到许多问题,也解决了很多问题,积累了一些心得,总体来说4是很大的进步!等这几篇比较基础的文档都翻译好了,再来写一些使用过程的心得和一些实例教程.
一个Ext JS 应用程序是由一或多个称为组件(components)的部件(widgets)组成的.所有的组件都是Ext.Component的子类,Ext.Component包含自动化生命周期管理的功能,如创建、渲染、尺寸控制、定位和销毁等,因此所有组件都自动拥有这些功能。ExtJS 提供了非常多可直接使用的组件,并且从这些组件继承并扩展自己的自定义组件也是很容易的一件事情。
组件层次结构
容器(Container)是一种可以包含其他组件的特殊组件。一个典型的应用程序是由许多按树状机构嵌套在一起的组件组成的,称之为组件层次结构。容器负责管理子组件的生命周期,包括子组件的创建、渲染、尺寸控制、定位和销毁。一个典型的应用程序组件层次结构一般使用Viewport作为顶级容器,它的子元素可以包含其他嵌套的容器或者非容器组件:
子组件使用容器的items属性配置添加到容器中。以下这个例子使用Ext.create创建了两个Panel,然后将这两个Panel作为子组件添加到一个Viewport中:
1: var childPanel1 = Ext.create('Ext.panel.Panel', {
2: title: 'Child Panel 1',
3: html: 'A Panel'
4: });
5:
6: var childPanel2 = Ext.create('Ext.panel.Panel', {
7: title: 'Child Panel 2',
8: html: 'Another Panel'
9: });
10:
11: Ext.create('Ext.container.Viewport', {
12: items: [ childPanel1, childPanel2 ]
13: });
容器使用布局管理器(Layout Managers)来管理容器中子组件的尺寸和定位。更多有关于布局管理和容器的知识请看:Layouts and Containers Guide(下一篇就翻译这篇)。关于布局管理和容器的demo:Container Example。
XType(组件类型)和延迟实例化
每个组件都有一个用来表示类型的名字,称为xtype。例如,组件Ext.panel.Panel的xtype为'panel'。所有组件的xtype在这里:API Docs for Component。上面那个例子展示了如何添加已经创建好的组件到容器中。 然而,在比较大的应用程序中,这样做不是很理想,因为并不是所有的组件都需要在声明时立即创建,甚至一些组件可能永远都不会被创建,这取决于你的程序中是如何使用这些组件的。例如:一个使用到Tab Panel(选项卡)的应用程序,选项卡的每一tab页只有在用户单击的时候才会去渲染。这时候xtype就派上用场了,在容器的子元素(items)配置中,为子元素指定xtype,子元素不会马上实例化,而是由容器决定子元素何时该实例化。
下面的示例代码演示如何延迟实例化和渲染容器中的子元素(使用Tab Panel)。每个tab页都会监听各自的渲染完成(rendered,在渲染结束后触发)事件,在渲染后弹出提示。
1: Ext.create('Ext.tab.Panel', {
2: renderTo: Ext.getBody(),
3: height: 100,
4: width: 200,
5: items: [
6: {
7: // Explicitly define the xtype of this Component configuration.
8: // This tells the Container (the tab panel in this case)
9: // to instantiate a Ext.panel.Panel when it deems necessary
10: xtype: 'panel',
11: title: 'Tab One',
12: html: 'The first tab',
13: listeners: {
14: render: function() {
15: Ext.MessageBox.alert('Rendered One', 'Tab One was rendered.');
16: }
17: }
18: },
19: {
20: // this component configuration does not have an xtype since 'panel' is the default
21: // xtype for all Component configurations in a Container
22: title: 'Tab Two',
23: html: 'The second tab',
24: listeners: {
25: render: function() {
26: Ext.MessageBox.alert('Rendered One', 'Tab Two was rendered.');
27: }
28: }
29: }
30: ]
31: });
1: var panel = Ext.create('Ext.panel.Panel', {
2: renderTo: Ext.getBody(),
3: title: 'Test',
4: html: 'Test Panel',
5: hideMode: 'visibility' // 使用 CSS visibility 属性 来显示和隐藏这个组件
6: });
7:
8: panel.hide(); // 隐藏组件
9:
10: panel.show(); // 显示组件
浮动组件
浮动组件,指的是使用css绝对定位(position:absolute)让组件脱离浏览器文档流,并且不参与其容器的布局。一些组件默认就是浮动的,如窗体组件(windows),并且所有组件都可以使用浮动(floating)属性设置为浮动。
1: var panel = Ext.create('Ext.panel.Panel', {
2: width: 200,
3: height: 100,
4: floating: true, // 使这个Panel成为一个使用绝对定位的浮动组件
5: title: 'Test',
6: html: 'Test Panel'
7: });
1: panel.show(); // 渲染并呈现panel,panel将被添加到body中,并且css定位属性为postion:absolute;
如果你使用浮动组件,以下这些配置需要注意下:
在线demo:Floating Panel Example
创建自定义组件
组合和扩展
要创建一个实现自己所需功能的自定义组件,你必须决定你要定义的组件(一般是一个类)是要包含一个组件的实例(组合),还是扩展一个组件(继承)。
建议将自己要实现的功能最相近的现有组件作为基类来扩展(尽量复用已有的功能)。这是因为如果你继承了现有组件,则你的组件就拥有自动管理生命周期不同阶段行为的功能,如:按需呈现,自定控制尺寸,根据布局管理器(layout manager)管理组件定位,从容器中移除时自动销毁等。
使用继承的方式去创建新的组件类比组合的方式更符合组件层次结构的要求,并且可以从类的外部去管理类本身。
子类
Ext的类系统(详见第一篇译文)让你可以很容易从现有组件中扩展。下面这个例子创建一个Ext.Component的子类,并且没有添加任何的扩展功能。
1: Ext.define('My.custom.Component', {
2: extend: 'Ext.Component'
3: });
模板方法
Extjs用模版方法模式(Template method pattern)委托到子类,方法的具体行为实现由具体的子类实现.
这意味着在组件的生命周期中,继承链里的每一个类都可以添加自己特定的逻辑。每个类都实现自己的特定逻辑,同时允许继承链中的其它类继续添加自己的逻辑。
渲染(render)方法即是一个典型的例子。render是组件(Component)超类中的一个私有方法,抽象组件(AbstractCompnent)负责启动组件生命周期中的呈现阶段。render不可以重载,但是render会调用onRender方法以允许子类在onRender中添加特定逻辑。每个onRender方法都必须在添加自己的特定逻辑之前先调用父类的onRender方法。
下图说明onRender模版方法的整个流程:
render方法首先被调用(由布局管理器负责),这个方法不允许重载,并且它是在Ext基类实现的。render内部调用在当前子类中实现的this.onRender方法(如果有实现的话).onRender内部又会调用父类的onRender方法.最终,每个子类中的onRender都添加了自己的功能,并且控制返回给render方法的值。
下面的例子是一个实现了onRender方法的组件子类。
值得注意的是,很多模版方法都拥有一个相应的事件.例如 render事件在组件渲染后触发.在子类中,很有必要使用模版方法来执行类生命周期中的各种逻辑,而不是使用事件.因为事件是可以被调用事件的代码暂停,或者被事件处理器停止的。
下面的列表是Component基类中已经实现的模版方法。
选择继承哪个类
考虑到开发效率问题,应该选择一个最佳的类来扩展,并且要考虑基类能提供哪些已有的功能。如果你有一堆组件集需要渲染和管理(即你的自定义组件是作为容器),则应尽量从Ext.Panel类继承.
Panel类有很多现有的功能:
如果不需要这些功能,则从Panel继承会浪费资源(应该考虑继承其他更简单的类).
组件
如果你要创建的组件不需要包含其他组件(不是作为容器),也就是说,它只是按你的需要封装了某种形式的HTML,那么,继承Ext.Component以实现自己的组件是最恰当的。例如,下面这个类是一个包含了一个HTML图片元素的组件,并且允许获取和设置图片的src属性。并且在图片加载完毕后触发一个load事件:
使用示例:
在线示例:在线示例。这个示例只是演示用的。在真实的开发场景中,应该使用Ext.Img类.
容器
如果你要创建的组件需要包含其他组件(即作为容器),但是你并不需要前面提到的Panel的各种功能,那从Ext.container.Container继承是最恰当的.使用容器,应该注意用来渲染和管理子组件的布局(Layout)是哪一种.
容器拥有以下模版方法:
Panel
如果你要创建的组件需要用到头部(header),页脚(footer)和工具条(toolbars),那从Ext.Panel扩展是最恰当的.
注意:Panel是一个容器,因此要记住使用哪种布局(Layout)来渲染和管理子组件。
继承Ext.Panel类以定义新组件通常是为应用程序高度定制的,并且通常使用布局配置用于聚合其他组件(一般是其他容器或者表单域),并且提供操作包含的组件和按钮的方法.
Panel拥有以下模版方法: