在《Ext2.0布局类初探》一文我简单的分析了一下Ext 2.0的布局类,但是缺乏例子。本篇文章的目的就是为《Ext2.0布局类初探》一文作补充,写几个简单的例子,希望大家能从中加深布局类的认识。因为没有API,对Ext2.0布局类也是一知半解,难免会有错误,请大家见谅!

一、简单的例子

这个例子和《Ext布局类的介绍与使用》(下称Ext文)的例子是一样的,大家可以通过两个例子对比一下2.0版的和1.1版的区别,整体布局图如下:

Ext 2.0布局实例_布局

和Ext文一样,我们先写好几个DIV:

  1. <div id="north-div"></div> 
  2. <div id="center-div">内容</div> 
  3. <div id="south-div">状态栏</div> 

和Ext文一样,没什么改变。

因为是对整个页面做布局的,所以需要使用Viewport类,而不是象1.1那样定义一个borderlayout,然后把document.body作为其容器。我们先创建一个Viewpot类:

  1. var viewport = new Ext.Viewport({  
  2.         layout:'border',  
  3.         items:[  
  4.         ]  
  5.    }); 

Viewprot类的创建很简单,只要定义一下布局的类型就行了,这里使用的是borderLayout。items就是我们需要定义布局和面板的地方。

我们首先加入north区域的面板定义(toolbar的定义我就不写了,和Ext文是一样的):

  1. var viewport = new Ext.Viewport({  
  2.         layout:'border',  
  3.         items:[  
  4.                {  
  5.                       border:false,  
  6.                       region:'north',  
  7.                 contentEl:'north-div',  
  8.                 tbar:tb,  
  9.                 height:26  
  10.                }  
  11.         ]  
  12.    }); 

在定义里,region属性指定了布局区域为north。因为borderLayout是有边的,而这里并不需要边,所以要设置border属性为false。面板的容器元件是id为north-div的DIV,所以contentEl设置“north-div”。这里设置了顶部工具栏(tbar)为定义好的tb。区域的高度是26。

在这里也可以使用Ext. BoxComponent代替borderLayout,好处嘛,我也说不上。如果用BoxComponent,需要修改几个地方,第一个地方是修改HTML:

  1. <div id="north-div"><div id="toolbar-div"></div></div> 

需要为工具栏增加一个div,因为BoxComponent里使用的是el属性指定它的容器,而不是用contentEl属性指定它的内容面板,所以要在容器里加一个工具栏的容器。完整代码如下:

  1. new Ext.BoxComponent({  
  2.                       region:'north',  
  3.                 el:'north-div',  
  4.                 tbar:tb,  
  5.                 height:26  
  6.                }) 

因为BoxComponent是没有边的容器,所以不用设置它的border属性。还有一个变动的地方就是el代替了contentEl,原因是el属性指定的div是BoxComponent的容器,而panel里contentEl指定的是面板容器。

我们继续写center区域的代码:

  1. new Ext.TabPanel({  
  2.                       region:'center',  
  3.             deferredRender:false,  
  4.             activeTab:0,  
  5.                       items:[{  
  6.                    contentEl:'center-div',  
  7.                    title: '内容',  
  8.                    closable:true,  
  9.                    autoScroll:true               
  10.                       }]  
  11.                }) 

因为center区域使用电话tab面板,不是用默认的panel面板,所以要创建一个TabPanel,region指定了区域位置是center,deferredRender设置是否延缓面板的加载,这里设置是同时加载,activeTab设置了当前活动的tab页是第1页,这个一定要设置,不然内容页面会显示为空白。在items里定义了一个tab页,它的内容面板使用了预先写好的id为center-div的div元件。注意这里定义的也是内容面板,不是布局的容器。其它的属性和1.1版的tabPanel是一样的,因此属性说明可参考1.1版的API,这里我就不详细说明了。

最后是完成south区域了:

  1. {  
  2.                      region:'south',  
  3.                      contentEl:'south-div',  
  4.                height:28,  
  5.                margins:'0 0 0 0'  
  6.               } 

在这里没什么特别的地方,只是将外补丁设置为0了。在这里也可以用BoxComponent代替,好处是背景色会和tab标签页头的背景一样,不用自己再设置。面板的默认背景色是白色,自己还要做相应的设置。

从代码中可以看到,新的写法不再需要:

  1. layout.beginUpdate();    
  2. layout.restoreState();   
  3. layout.endUpdate(); 

这样的好处就是使代码更加清晰明了,不会遗漏代码,尤其是当内部布局再划分的时候。

例子的完整代码如下:

  1. Ext.onReady(function(){  
  2.               var tb=new Ext.Toolbar('north-div');//创建一个工具条  
  3.          tb.add(new Ext.Toolbar.SplitButton({  
  4.            text: '文件',  
  5.            cls: 'x-btn-text-icon blist',  
  6.            menu : {items: [  
  7.              {text: '新建', handler: onItemClick},  
  8.              {text: '保存', handler: onItemClick},  
  9.              {text: '加载', handler: onItemClick}  
  10.            ]}}),  
  11.            new Ext.Toolbar.MenuButton({  
  12.            text: '编辑',  
  13.            cls: 'x-btn-text-icon blist',  
  14.            menu : {items: [  
  15.              {text: '复制', handler: onItemClick},  
  16.              {text: '粘贴', handler: onItemClick}  
  17.            ]}})  
  18.          );  
  19.    var viewport = new Ext.Viewport({  
  20.         layout:'border',  
  21.         items:[  
  22.                {  
  23.                       border:false,  
  24.                       region:'north',  
  25.                       contentEl:'north-div',  
  26.                       tbar:tb,  
  27.                       height:26  
  28.                },  
  29.                new Ext.TabPanel({  
  30.                       region:'center',  
  31.             deferredRender:false,  
  32.             activeTab:0,  
  33.                       items:[{  
  34.                    contentEl:'center-div',  
  35.                    title: '内容',  
  36.                    closable:true,  
  37.                    autoScroll:true               
  38.                       }]  
  39.                }),  
  40.                {  
  41.                       region:'south',  
  42.                       contentEl:'south-div',  
  43.                 height:28,  
  44.                 margins:'0 0 0 0' 
  45.                }  
  46.         ]  
  47.    });  
  48.       function onItemClick(item){  
  49.              alert(item.text);  
  50.       }  
  51.  }) 

最终效果图:

Ext 2.0布局实例_实例_02 

Ext文第二个例子布局一样:

Ext 2.0布局实例_实例_03

第一步还是根据布局写好html代码:

  1. <div id="north-div"><div id='toolbar-div'></div></div> 
  2. <div id="west-div"></div> 
  3. <div id='center-center'></div> 
  4. <div id='center-south'></div> 
  5. <div id="south-div">状态栏</div> 

这次north区域我们尝试使用BoxComponent

  1. new Ext.BoxComponent({  
  2.              region:'north',  
  3.              el:'north-div',  
  4.              tbar:tb,  
  5.              height:26  
  6.       }) 

这里的代码在简单的例子已经介绍过了我就不多说了。下面然后开始写west区域定义。因为west区域是一个树列表,用到treePanel,需要一个根节点,所以在viewport前代码前先加入根节点:

  1. var root = new Ext.tree.TreeNode({  
  2.         text: '文件夹',   
  3.         allowDrag:false,  
  4.         allowDrop:false  
  5.     });  
  6.  
  7.     root.appendChild(  
  8.         new Ext.tree.TreeNode({text:'收件箱',allowDrag:false}),  
  9.         new Ext.tree.TreeNode({text:'发件箱',allowDrag:false}),  
  10.         new Ext.tree.TreeNode({text:'联系人',allowDrag:false}),  
  11.         new Ext.tree.TreeNode({text:'已删除的邮件',allowDrag:false})  
  12.     ); 

当然了,这个你也可以在界面完成后通过节点操作再加。我们现在可以写west区域的定义了:

  1. new Ext.tree.TreePanel({  
  2.              region:'west',  
  3.              contentEl:'west-div',  
  4.              title:'树列表',  
  5.       split:true,  
  6.       width: 200,  
  7.       minSize: 175,  
  8.       maxSize: 400,  
  9.       collapsible: true,  
  10.       margins:'0 0 0 0',  
  11.       root:root  
  12.       }) 

这里比较特别的地方就是用TreePanel代替了默认的panel,设置了一个根节点root为先前定义的“root”变量。和Ext文对比一下,是不是简单了很多?不用在布局容器里再定义一个div来放置树了,省去了树的创建代码。下面来定义center区域:

  1. {  
  2.              region:'center',  
  3.              layout:'border',  
  4.              items:[  
  5.                     new Ext.grid.GridPanel({  
  6.                            region:'center',  
  7.                            el:'center-center',  
  8.                            title:'条目列表',  
  9.                     ds: ds,  
  10.                     cm: colModel,  
  11.                autoScroll: true  
  12.                     }),  
  13.                     {  
  14.                            region:'south',  
  15.                            contentEl:'center-south',  
  16.                            title:'内容',  
  17.                          split:true,  
  18.                            collapsible:true,  
  19.                            titlebar:true,  
  20.                            height:200,  
  21.                            minSize: 100,  
  22.                            maxSize:400,  
  23.                            collapsedTitle:'内容'  
  24.                      }  
  25.              ]  
  26.       } 
从代码中可以看到,我们不指定在html代码中定义的div作为它的内容面板,它自己会去创建。我们只需要定义它的区域位置(region)为center。这里有一个很重要的定义,就是layout属性了,这里的属性值为“border”,意思就是其内部布局的划分是使用borderlayout作为布局的。

从代码中可以看到,我们不指定在html代码中定义的div作为它的内容面板,它自己会去创建。我们只需要定义它的区域位置(region)为center。这里有一个很重要的定义,就是layout属性了,这里的属性值为“border”,意思就是其内部布局的划分是使用borderlayout作为布局的。然后我们在items中划分两个布局,一个是center区域的表格,和south区域的内容显示面板。因为需要显示表格,所以直接创建了一个GridPanel作为center区域的面板。它的属性定义和1.1版的没有太大区别。在这里只需要说明该区域的位置(center)和它的容器(el)是我们定义好的it为“center-center”的div。内部south区域的定义也没什么特殊的地方,这里就不一一说明了。最后我们加入整体布局south区域的定义就完成了我们这里例子。这里south也采用BoxComponent,而不采用panel:

  1. new Ext.BoxComponent({  
  2.              region:'south',  
  3.              el:'south-div',  
  4.              height:24  
  5.       }) 

例子的完整代码:

  1. Ext.onReady(function(){  
  2.               var tb=new Ext.Toolbar('toolbar-div');//创建一个工具条  
  3.          tb.add(new Ext.Toolbar.SplitButton({  
  4.            text: '文件',  
  5.            cls: 'x-btn-text-icon blist',  
  6.            menu : {items: [  
  7.              {text: '新建', handler: onItemClick},  
  8.              {text: '保存', handler: onItemClick},  
  9.              {text: '加载', handler: onItemClick}  
  10.            ]}}),  
  11.  
  12.            new Ext.Toolbar.MenuButton({  
  13.            text: '编辑',  
  14.            cls: 'x-btn-text-icon blist',  
  15.            menu : {items: [  
  16.              {text: '复制', handler: onItemClick},  
  17.              {text: '粘贴', handler: onItemClick}  
  18.            ]}})  
  19.          );  
  20.  
  21.     var root = new Ext.tree.TreeNode({  
  22.         text: '文件夹',   
  23.         allowDrag:false,  
  24.         allowDrop:false  
  25.     });  
  26.  
  27.     root.appendChild(  
  28.         new Ext.tree.TreeNode({text:'收件箱',allowDrag:false}),  
  29.         new Ext.tree.TreeNode({text:'发件箱',allowDrag:false}),  
  30.         new Ext.tree.TreeNode({text:'联系人',allowDrag:false}),  
  31.         new Ext.tree.TreeNode({text:'已删除的邮件',allowDrag:false})  
  32.     );  
  33.  
  34.     var myData = [  
  35.                      ['张三','测试','2006-1-1'],  
  36.                      ['李四','测试一','2006-5-6'],  
  37.                      ['王五','测试二','2007-12-1'],  
  38.                      ['刘六','测试三','2006-12-1'],  
  39.                      ['张三','测试四','2007-6-1'],  
  40.                      ['李四','测试五','2007-7-1'],  
  41.                      ['刘六','测试六','2007-8-1'],  
  42.                      ['张三','测试七','2007-9-1'],  
  43.                      ['李四','测试八','2007-10-1'],  
  44.                      ['王五','测试九','2007-11-1'],  
  45.                      ['刘六','测试六','2007-8-1'],  
  46.                      ['张三','测试七','2007-9-1'],  
  47.                      ['李四','测试八','2007-10-1'],  
  48.                      ['王五','测试九','2007-11-1'],  
  49.                      ['刘六','测试十','2007-8-1'],  
  50.                      ['张三','测试十一','2007-9-1'],  
  51.                      ['李四','测试十二','2007-10-1'],  
  52.                      ['王五','测试十三','2007-11-1'],  
  53.                      ['刘六','测试十四','2007-8-1'],  
  54.                      ['张三','测试十五','2007-9-1'],  
  55.                      ['李四','测试十六','2007-10-1'],  
  56.                      ['王五','测试十七','2007-11-1'],  
  57.                      ['刘六','测试十八','2007-8-1']  
  58.               ];  
  59.  
  60.     var ds = new Ext.data.Store({  
  61.       proxy: new Ext.data.MemoryProxy(myData),  
  62.       reader: new Ext.data.ArrayReader({}, [  
  63.        {name:'sender'},  
  64.        {name:'title'},  
  65.        {name:'sendtime'}  
  66.       ])  
  67.     });  
  68.     ds.load();  
  69.  
  70.     var colModel = new Ext.grid.ColumnModel([  
  71.                      {header:'发送人',width:100,sortable:true,dataIndex:'sender'},  
  72.                      {id:'title',header:'标题', width:100,sortable:true,dataIndex:'title'},  
  73.                      {header:'发送时间',width:75,sortable:true,dataIndex:'sendtime'}  
  74.               ]);  
  75.  
  76. var viewport = new Ext.Viewport({  
  77.   layout:'border',  
  78.   items:[  
  79.       new Ext.BoxComponent({  
  80.              region:'north',  
  81.              el:'north-div',  
  82.              tbar:tb,  
  83.              height:26  
  84.       }),  
  85.  
  86.       new Ext.tree.TreePanel({  
  87.              region:'west',  
  88.              contentEl:'west-div',  
  89.              title:'树列表',  
  90.       split:true,  
  91.       width: 200,  
  92.       minSize: 175,  
  93.       maxSize: 400,  
  94.       collapsible: true,  
  95.       margins:'0 0 0 0',  
  96.       root:root  
  97.       }),  
  98.  
  99.       {  
  100.              region:'center',  
  101.              layout:'border',  
  102.              items:[  
  103.                     new Ext.grid.GridPanel({  
  104.                            region:'center',  
  105.                            el:'center-center',  
  106.                            title:'条目列表',  
  107.                     ds: ds,  
  108.                     cm: colModel,  
  109.                autoScroll: true  
  110.                     }),  
  111.  
  112.                     {  
  113.                            region:'south',  
  114.                            contentEl:'center-south',  
  115.                            title:'内容',  
  116.                          split:true,  
  117.                            collapsible:true,  
  118.                            titlebar:true,  
  119.                            height:200,  
  120.                            minSize: 100,  
  121.                            maxSize:400,  
  122.                            collapsedTitle:'内容'  
  123.                      }  
  124.              ]  
  125.       },  
  126.       new Ext.BoxComponent({  
  127.              region:'south',  
  128.              el:'south-div',  
  129.              height:24  
  130.       })  
  131.   ]  
  132. });  
  133.  
  134. root.expand()  
  135.       function onItemClick(item){  
  136.              alert(item.text);  
  137.       }  
  138.  }) 

最终的效果如下:

Ext 2.0布局实例_文章_04

通过两个例子,第一感觉就是Ext2.0的布局更简化和层次化了。不过发现了一个小bug,就是在缩小浏览器窗口的时候,如果center区域内部的south区域过大的话,会把center区域遮盖,这可能是我没有完全理解布局的书写规则造成。这篇文章只是起一个抛砖引玉的作用,给大家使用Ext2.0进行页面布局做一个简单的介绍。因为个人水平有限和理解的偏差,会有不少错误,请大家见谅!如果大家在Ext2.0布局设计中碰到任何问题或疑问,欢迎与我联系,大家一起共同探讨,多谢!

本文的例程可点击这里下载。