布局(layout)系统是ExtJS中较为强大的模块之一,它负责处理每一个组件(component)的大小和位置,下面主要就是讲布局的入门的。
容器:
一个ExtJS的应用程序UI(用户界面)是由组件(components)组成的,关于组件(component)会有有一个专页对其讲解,容器(container)则是一个特殊的组件,只不过它包含了其它的组件。一个典型的应用程序是由许多容器及其内嵌的多个组件构成的。
最常用的一个组件就是面板(panel),下面可以看一下让这个容器是如何建立并包含其它组件的:
Ext.create('Ext.panel.Panel', {
renderTo:Ext.getBody(),
width: 400,
height: 300,
title: 'ContainerPanel',
items: [
{
xtype:'panel',
title: 'ChildPanel 1',
height: 100,
width: '75%'
},
{
xtype:'panel',
title: 'ChildPanel 2',
height: 100,
width: '75%'
}
]
});
在本例子中,我们仅仅是创建了一个面板pannel渲染到文档body中了,然后我们使用items属性给panel容器添加了两个子panel面板。
布局:
每一个容器都有一个布局(layout),它管理容器的子组件的位置和大小,下面会讲到如何使用特定的布局配置一个容器、布局系统如何让所有组件保持协调一致的。
使用布局:
上面的例子中,我们没有给panel容器指定一个布局layout,但依旧可以看一下子panel组件是如歌一个一个排列的,很像在DOM文件中block元素的表现。之所以会这样显示是因为所有的容器默认给设置的就是auto
layout自动布局,它没有给子元素指定任何的位置和大小。我们假定想要让两个子panel肩并肩排列,每个排列均分50%,我们就可以给容器使用column布局。
Ext.create('Ext.panel.Panel', {
renderTo:Ext.getBody(),
width: 400,
height: 200,
title: 'ContainerPanel',
layout: 'column',
items: [
{
xtype: 'panel',
title: 'ChildPanel 1',
height: 100,
columnWidth:0.5
},
{
xtype:'panel',
title: 'ChildPanel 2',
height: 100,
columnWidth:0.5
}
]
});
ExtJS自带一系列的布局,能够满足你能想象到的所有布局,可以在布局专门章节实战不同类型的layouts布局。
布局系统如何起作用
容器的布局牵涉到容器内所有子组件的位置和大小,框架会在内部调用容器的updateLayout方法,次方法就会去计算和校正容器内子元素的大小和位置并更新到DOM。UpdateLayout方法是递归的,所以子元素的updateLayout方法也会同样被调用,直到所有子容器都被执行完成才结束。因为框架会自动进行调用,所以对开发者来说一般不需要手动调用该方法。
当容器进行resize调整大小时或者当子组件添加或删除的时候
重新布局(re-layout)就会被触发, 正常情况下我们不会手动去调用这个更新布局的方法,但是有时候,我们会有一个需求就是先阻止自动更新,等批量组件完成之后再统一调用一次更新,为了满足这个需求,我们可以给容器使用suspendLayout标识阻止自动更新,当批量更新完成的时候再调回标识,并调用updateLayout方法进行统一更新:
var containerPanel = Ext.create('Ext.panel.Panel', {
renderTo:Ext.getBody(),
width: 400,
height: 200,
title: 'ContainerPanel',
layout: 'column',
suspendLayout: true// Suspend automatic layouts while we do several different things that couldtrigger a layout on their own
});
// Add a couple of child items. We could add these both at the same time by passing an array to add(),
// but lets pretend we needed to add them separately for somereason.
containerPanel.add({
xtype: 'panel',
title: 'Child Panel1',
height: 100,
columnWidth: 0.5
});
containerPanel.add({
xtype: 'panel',
title: 'Child Panel2',
height: 100,
columnWidth: 0.5
});
// Turn the suspendLayout flag off.
containerPanel.suspendLayout = false;
// Trigger a layout.
containerPanel.updateLayout();
组件布局
跟容器和布局中定义大小和位置一样,组件也有一个布局定义自己内部子元素的大小和位置的,这个配置属性就是componentLayout。
通常情况下,你不需要配置这个属性,除非你自定义一个组件并且所有的组件都有自己的布局管理器,大部分的组件使用自动布局,但是更多复杂的组件就需要自定义的布局(比如一个拥有头部底部和工具条的面板)。