所有组件都是Ext.Component类的子类,Ext.Component类允许它们具有自动生命周期管理包括实例化、渲染、大小和定位、和毁灭。
一、组件层次结构
容器是一种特殊的组件,可以包含其他组件。一个典型的应用程序是由
树状结构中的许多嵌套组件组成的,被称为组件的层次结构。容器负责管理子组件的生命周期,包括创建、渲染、大小和定位、和毁灭。一个典型的应用程序的组件层次结构开始于一个
Viewport,其他容器或组件嵌套在它里面:
子组件使用容器的
items配置属性
添加到一个容器中。
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 ]
});
二、XTypes和延迟实例化
每个组件都有一个名为xtype的符号名。例如Ext.panel。面板有一个 “panel”的xtype。上面的例子展示了如何添加已经实例化组件到容器。在一个大型的应用程序中,这并不理想,因为并不是所有的组件需要马上被实例化,一些组件可能永远不会被实例化,这取决于应用程序是如何使用组件的。例如一个应用程序,它使用一个选项卡面板,只需要 当用户点击选项卡时,选项卡的内容呈现 。这时xtypes派上用场,允许一个容器的组件预先配置,但没有实例化直到容器确定它是必要的。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,所以它的容器标签面板实例化和立即呈现它。
三.显示和隐藏
所有组件在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
四、浮动组件
浮动组件在定位文档流之外使用CSS绝对定位,不参与容器的布局。一些组件如窗口在默认情况下是漂浮,但任何组件都可以使用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'
});
上面的代码实例化了一个面板,但没有渲染它。通常一个组件要么有一个renderTo的配置,或
作为子组件添加到容器中,但浮动组件不需要这些。
当show方法第一次被调用时,浮动组件自动渲染到文档主体中:
panel.show(); // render and show the floating panel
与浮动组件有关的其他配置和方法:
五、创建自定义组件
render方法被调用(这是由一个容器的布局管理器)。这种方法不会被重载,是通过Ext基类执行的。它在当前子类中调用this.onRender
。它调用父类的版本,父类调用其基类版本等等。最终,每个类都贡献了自己的函数,并且控制返回到render函数。
Ext.define('My.custom.Component', {
extend: 'Ext.Component',
onRender: function() {
this.callParent(arguments); // call the superclass onRender method
// perform additional rendering tasks here.
}
});
下面是
可以由组件子类实现的模板方法,:
选择最好的类来扩展主要是一个效率的问题。每当任何一组UI组件需要被渲染和管理时,扩展Ext.Panel是一种趋势。
initComponent
:被构造函数调用,用来初始化数据、设置配置、附加事件处理程序beforeShow:在组件显示之前调用
onShow
:在显示操作中添加行为。调用超类的onShow之后,组件是可见的afterShow
:组件显示之后调用onShowComplete
:afterShow函数执行完成后调用onHide
:在隐藏操作中添加行为。 调用超类的onHide之后,组件不可见afterHide
:组件隐藏之后调用onRender
:在渲染阶段添加行为afterRender
:在渲染完成之后添加行为。在这种情况下组件的元素会根据配置设计,可以添加配置过的CSS类名,并处于配置的可见性和配置的启用状态onEnable
:在 enable操作中添加行为。调用超类的 onEnable之后,组件将启用onDisable
:在disable 操作中添加行为。调用超类的 onDisable之后,组件将禁用onAdded
:当组件添加到容器中时,添加行为。在这个阶段组件已经在父容器中。调用超类的onAdded之后,ownerCt 将会出现,如果配置了ref, refOwner 也将被设置onRemoved
:当组件从容器中一处时,添加行为。在这个情况下,组件已经从容器中移除, 但还没有销毁(如果父容器的autoDestroy为true时,自动销毁)。调用超类的onRemoved之后, ownerCt和 refOwner 不会出现onResize
:在resize操作中添加行为onPosition
:在position 操作中添加行为onDestroy
:在 destroy 操作中添加行为。 调用超类的onDestroy之后,组件被销毁beforeDestroy
:组件销毁之前调用afterSetPosition
:组件位置设定好之后调用afterComponentLayout
:组件布局之后调用beforeComponentLayout
:组件布局之前调用
六、扩展哪个类
面板类有许多功能:
- 边框
- 页面
- 标题栏工具条
- 页脚
- 页脚按钮
- 顶部的工具栏
- 底部的工具栏
- 包含并管理子组件
1.组件
如果所需的UI组件不需要包含任何其他组件,即如果它只是来封装某种形式的执行需求的HTML,扩展Ext.Component是合适的。例如,下面的类是一个组件,它封装一个HTML图像元素,并允许设置和获取图像的src属性。当映像被加载时,它还触发一个加载事件:
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');
2.容器
如果所需的UI组件是包含其他组件,但不需要任何前面提到的面板的额外功能,扩展Ext.container。在容器水平上,要记用哪个布局来渲染和管理的子组件。容器有下列可附加模板方法:
onBeforeAdd
:在添加新的子组件之前调用。它可以修改组件,以某种方式准备容器,返回false终止添加操作。onAdd
:新组建被添加之后调用。 可以用来修改任何内部结构,取决于子条目的状态。onRemove:在新组件一处之后调用。
可以用来修改任何内部结构,取决于子条目的状态。beforeLayout:在容器为子组件布局之前调用。
afterLayout
:在容器为子组件布局之后调用。
3.面板
如果所需的UI组件必须有一个页眉、页脚或者工具栏,Ext.Panel是合适的扩展类。
面板有下列可附加模板方法:
afterCollapse
:在面板收缩之后调用afterExpand:在面板扩展之后调用
onDockedAdd
:在停靠条目添加打面板之后调用onDockedRemove:在停靠条目从面板中移除之后调用