【翻译】Ext4.1.3--Layouts and Containers(布局和容器)

时间:2021-05-06 08:54:06

  原文链接:http://docs.sencha.com/ext-js/4-1/#!/guide/layouts_and_containers

  布局系统是ExtJS中最为强大的部分之一。它用于处理你的应用中所有组件的大小和位置。这个指南通过介绍若干基本概念,来告诉你怎么样开始编写布局。

  容器

  一个Ext JS应用的UI由若干组件(Component)组成,容器(Container)是组件的一个具体的类型,他可以包含其他组件。一个典型的Ext JS应用是由许多层嵌套的组件组成:

  【翻译】Ext4.1.3--Layouts and Containers(布局和容器)

  最常用的容器是面板(Panel)。让我们来看看如何在面板的基础上创建子组件。

 1 Ext.create('Ext.panel.Panel', {
 2     renderTo: Ext.getBody(),
 3     width: 400,
 4     height: 300,
 5     title: 'Container Panel',
 6     items: [
 7         {
 8             xtype: 'panel',
 9             title: 'Child Panel 1',
10             height: 100,
11             width: '75%'
12         },
13         {
14             xtype: 'panel',
15             title: 'Child Panel 2',
16             height: 100,
17             width: '75%'
18         }
19     ]
20 });

  我们刚刚在body元素下创建了一个面板,然后通过配置(items)给面板容器加上了两个子面板。

  布局

  每一个容器都拥有一个布局对象来管理子组件的大小和位置。在下面的这个部分中,我们详述一下怎么给容器配置一个特殊的布局对象,还有,布局系统是怎么使得一切保持同步的。

  使用布局

  在上面的例子中我们没有给面板容器采用一个特定的布局。你若观察一下这两个子面板是如何一个接一个地摆放的(代码的具体运行效果见原链接,ps:可以在原链接中修改代码再运行),便不难发现他的布局方式和普通的block元素在DOM中的表现一致。这是因为所有容器的默认的布局方式是自动布局(Auto Layout)。自动布局没有对子组件的大小和宽度做任何的变动。接下来,我们来实现一个布局,我们想让两个子面板并排的排在一行,并且每个子面板各占父容器的50%的宽度。我们可以简单地使用列布局(Column Layout),给容器加上一个layout配置即可:

  

 1 Ext.create('Ext.panel.Panel', {
 2     renderTo: Ext.getBody(),
 3     width: 400,
 4     height: 200,
 5     title: 'Container Panel',
 6     layout: 'column',
 7     items: [
 8         {
 9             xtype: 'panel',
10             title: 'Child Panel 1',
11             height: 100,
12             columnWidth: 0.5
13         },
14         {
15             xtype: 'panel',
16             title: 'Child Panel 2',
17             height: 100,
18             columnWidth: 0.5
19         }
20     ]
21 });

  除此之外,Ext JS还提供了一系列的布局方式来满足任何你能想到的布局效果。可以查看一下Layout Browser,以便了解哪些布局效果是可行的。

  布局系统是怎么工作的

  一个容器的布局属性负责初始化该容器的所有子组件的大小和位置。框架内部是调用容器的doLayout方法来触发布局计算,计算得出容器的所有子组件大小和位置信息,并设置到相应的DOM上。doLayout方法是递归调用的,所以该容器的任何子容器的doLayout方法也会被调用。直到达到位于层级底部的子组件,才会停止继续的往下递归调用。一般情况下,在应用中你都不需要自己的调用doLayout方法,框架会帮你自动进行布局的计算。

  当容器的大小变化,或容器新增或移除子组件时,会触发容器的重新布局(re-layout)。普通情况下,框架会处理好这个重新布局的过程。但是,当我们想批量的进行会触发重新布局的相关操作时,我们会需要阻止让框架自动的进行布局计算(优化性能)。这就需要我们设置suspendLayout标志为true,所有操作完毕后自己再调用一下doLayout方法:

  

 1 var containerPanel = Ext.create('Ext.panel.Panel', {
 2     renderTo: Ext.getBody(),
 3     width: 400,
 4     height: 200,
 5     title: 'Container Panel',
 6     layout: 'column',
 7     suspendLayout: true // Suspend automatic layouts while we do several different things that could trigger a layout on their own
 8 });
 9 // Add a couple of child items.  We could add these both at the same time by passing an array to add(),
10 // but lets pretend we needed to add them separately for some reason.
11 containerPanel.add({
12     xtype: 'panel',
13     title: 'Child Panel 1',
14     height: 100,
15     columnWidth: 0.5
16 });
17 containerPanel.add({
18     xtype: 'panel',
19     title: 'Child Panel 2',
20     height: 100,
21     columnWidth: 0.5
22 });
23 // Turn the suspendLayout flag off.
24 containerPanel.suspendLayout = false;
25 // Trigger a layout.
26 containerPanel.doLayout();

  组件的布局

  容器的布局用来决定其子组件的大小和位置,组件的布局也和他类似,用来决定组件的子项(items)的大小和位置。组件的布局需要配置componentLayout属性。所有已提供的组件都会依据其布局方式计算出其内部DOM元素大小和位置信息,一般情况下,你不需要使用这个配置,除非你需要写一个自定义组件。大多数的组件都使用的自动布局,有一些复杂的组件会需要一些自定义的组件布局方式,例如一个有头部、尾部和工具栏的Panel