布局系统(layout system)是ExtJS最强大的部分之一,它掌控你应用中的每一个组件的大小和位置,这篇文章函盖了怎样开始使用布局,是ExtJS 4布局的初级教程。

Containers 容器

ExtJS应用的UI界面,是由组件(Component)构建起来的,容器(Container)是一个特殊的组件,它可以盛放其他组件,每个典型的ExtJS应用都是数层嵌套的组件组成的。如图所示:

component_architecture.png

最常用的容器,就是Panel,让我们见识一下,作为一个容器,Panel是如何盛放其他组件的:

Ext.create('Ext.panel.Panel', {
    renderTo: Ext.getBody(),
    width: 400,
    height: 300,
    title: 'Container Panel',
    items: [
        {
            xtype: 'panel',
            title: 'Child Panel 1',
            height: 100,
            width: '75%'
        },
        {
            xtype: 'panel',
            title: 'Child Panel 2',
            height: 100,
            width: '75%'
        }
    ]
});

我们仅仅创建了一个Panel,让它渲染到文档主体body中,然后我们使用了items配置,添加了两个子Panel到容器Panel中。

Layouts 布局

每个容器都有布局用来管理子组件的大小和位置,这一节我们讨论如何应用一个特定的布局,布局是怎样工作的

Using Layouts 使用布局

上面的例子中我们没有给Panel指定布局,但是注意Panel中的子Panel都是按照顺序从上到下排列的,就像块状元素在DOM中的表现一样,这是因为容器的默认布局就是Auto LayoutAuto Layout不给下级组件指定大小和位置,因此就是从上到下排列。假如我们想要两个子Panel并排横着排列,各占父容器50%的宽度,我们就可以使用Column Layout,只要给父容器指定layout配置即可:

Ext.create('Ext.panel.Panel', {
    renderTo: Ext.getBody(),
    width: 400,
    height: 200,
    title: 'Container Panel',
    layout: 'column',
    items: [
        {
            xtype: 'panel',
            title: 'Child Panel 1',
            height: 100,
            columnWidth: 0.5
        },
        {
            xtype: 'panel',
            title: 'Child Panel 2',
            height: 100,
            columnWidth: 0.5
        }
    ]
});

还要注意一点,子Panel中增加了columnWidth属性用来控制宽度各50%,ExtJS的布局基本上可以满足你所有布局需要

How the layout system works 布局系统如何工作

容器自身的布局属性负责掌控它的子容器的初始尺寸和位置,ExtJS框架内部会调用容器的doLayout方法触发Layout System计算子容器的大小和位置并更新DOM,doLayout方法是递归的,就是说当一个容器执行了doLayout,它的每层下级容器,都会按照层级顺次调用,直到最内层的容器。通常不需要自己调用doLayout方法,框架会负责这件事。

容器改变尺寸的时候会重新布局,有子容器添加删除也会触发容器重新布局,一般只需要依靠框架自身掌控重新布局即可,但是有些情况我们想禁止自动重新布局,当操作都结束之后一次性重新布局(例如循环添加了几十个子容器,每添加一次就重新布局效率较差,全部添加完之后一次从新布局即可),这时候可以利用suspendLayout标志位置为true阻止一些通常会自动触发重新布局的行为,当操作完成之后关闭这个标志位再手动doLayout,例如:

var containerPanel = Ext.create('Ext.panel.Panel', {
    renderTo: Ext.getBody(),
    width: 400,
    height: 200,
    title: 'Container Panel',
    layout: 'column',
    suspendLayout: true // Suspend automatic layouts while we do several different things that could trigger 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 some reason.
containerPanel.add({
    xtype: 'panel',
    title: 'Child Panel 1',
    height: 100,
    columnWidth: 0.5
});
containerPanel.add({
    xtype: 'panel',
    title: 'Child Panel 2',
    height: 100,
    columnWidth: 0.5
});
// Turn the suspendLayout flag off.
containerPanel.suspendLayout = false;
// Trigger a layout.
containerPanel.doLayout();

Component Layout 组件中的布局

(这一段说的是组件自身,例如一个Panel组件的自身的元素是如何布局)就像容器有布局一样,组件也有布局定义内层组件的尺寸,组件的布局使用componentLayout配置项,通常你不需要使用这个设置,除非自定义一个组件,因为所有现有组件都有默认的布局管理器,通常都是Auto Layout,但是复杂的组件例如Panel就需要一个不一样的布局(因为它有header,footer,toolbar等需要掌管)

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐