标签:extjs4 components 组件 javascript
一个Ext JS 应用的UI是由一个或多个叫做组件(Component)的小部件组成的。所有的组件都是Ext.Component的子类,Ext.Component可以使其子类参与自动化的声明周期管理,包括初始化、渲染、调整大小及位置和销毁。Ext JS提供了大量的直接可用的组件,并且任何组件都能够被轻松的继承从而实现定制化的组件。
容器是一个可以容纳其他组件的一种特殊组件。一个典型的应用程序是由多个嵌套的树状层次结构的组件组成的。容器负责管理它的子组件的生命周期,包括创建、渲染、调整大小及位置、销毁。一个典型的应用程序组件层次结构以一个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 ] });
每个组件都有一个符号名叫做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.'); } } } ] });
直到第二个标签页被点击它的提示框才会显示出来。这就说明这个标签页并没有被渲染直到需要它的时候,因为render方法并没有被触发直到这个标签页被激活。
例子代码可以在Ext JS 4 SDK提供的例子中找到
所有的组件都有内建的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的绝对定被位置于文档流之外,并且不参与它容器的布局。一些组件(例如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.show(); // render and show the floating panel
你可以在Ext JS 4 SDK的例子中找到浮动Panel的例子
当创建一个新的UI类时,你必须确定你的类时Component的一个实例还是继承自一个组件。
这里强烈推荐继承一个和你需要功能相近的基类。这是因为Ext JS 提供的自动化生命周期管理将会被合适的布局管理器管理并且在从容器中移除时会自动销毁。
很简单就能写一个新的组件类,并且它能够在组件层次结构中占有一席之地,而不是一个包含Ext JS 组件的新类,还必须在外部对它进行渲染和管理。
类系统(见【ExtJS 4.x学习教程】(1)类系统(Class System))能够让你很简单就能继承一个已存在的组件。下边的例子创建了一个Ext.Component的子类,而没有添加任何额外的功能:
Ext.define('My.custom.Component', { extend: 'Ext.Component' });
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. } });
下边是可以被组件子类实现的模板方法:
选择最好的类来扩展主要是效率问题,以及考虑基类必须提供哪些能力。以前的版本总是趋向于总是继承自Ext.Panel,无论需要被渲染和管理的组件到底是什么
Panel类有很多能力:
如果这些能力不是必须的,那使用Panel就是对资源的一种浪费。
如果需要的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');
如果你需要的UI组件需要包含其他的组件,但是不需要前边提到的Panel的功能,那么继承Ext.container.Container比较合适。在容器层,记住用那个Layout来渲染和管理子组件很重要。
容器有下边额外的模板方法:
如果你的UI组件必须有header,footer,或者toolbar,继承Ext.Panel会比较合适。
注意:一个Panel是一个容器。记住使用哪个Layout去渲染和管理它的子组件很重要。
继承自Ext.Panel的类通常是高度特定于应用的,并且通常使用Layout和其他的UI组件(通常是容器和form表单)一起使用,通过tbar和bbar的控制方式提供它所容纳的组件的操作方式。
Panel有如下额外的模板方法:
本文主要讲述了Ext JS 4的组件模型,一些常用组件,以及怎么定制一个组件。通过学习本文,你能够很好的了解Ext JS 4 组件模型的全貌,并能够新建一个组件类时,采用正确的方式。
【ExtJS 4.x学习教程】(4)组件(Components),布布扣,bubuko.com
【ExtJS 4.x学习教程】(4)组件(Components)
标签:extjs4 components 组件 javascript
原文地址:http://blog.csdn.net/zhoubangtao/article/details/27366477