6.1 布局的用途
1 6.1 布局的用途 2 //決定把什么東西放到什么位置; 3 var vieport = new Ext.Viewport({ 4 layout:'border', //使用BorderLayout的布局方式(邊界布局);可以自動檢測瀏覽器的大小變化和自動調整布局中每個部分的大小; 5 items:[{ 6 region:'north', //指定組件的具體位置; 7 height:40, 8 html:'<h1>頂部</h1>' 9 },{ 10 region:'west', 11 width:100, 12 html:'<p>左側區域</p>' 13 },{ 14 region:'center', 15 html:'主要內容' 16 }] 17 }); 18 //Ext的所有布局都是從Ext.Container開始的,Ext.Container的父類是Ext.BoxComponent; 19 //Ext.BoxComponent是一個盒子組件,可以定義寬度/高度和位置等; 20 21 //Ext.Container及其子類 22 >.Ext.Container //Ext.Container的子類都可以用layout對內部的items進行布局; 23 >.Ext.Viewport 24 >.Ext.Panel 25 >.Ext.TabPanel 26 >.Ext.Tip 27 >.Ext.Window 28 >.Ext.form.FieldSet 29 >.Ext.form.FormPanel 30 >.Ext.tree.TreePanel 31 >.Ext.grid.GridPanel 32 >.Ext.grid.EditorGridPanel 33 >.Ext.grid.PropertyGrid 34 35 //所有布局類也有一個共同的超類Ext.layout.ContainerLayout 36 //凡是該超類的子類都可以對Ext.Container及其子類進行布局定義; 37 >.Ext.layout.ContainerLayout //容器布局 38 >.Ext.layout.AnchorLayout //錨點布局 39 >.Ext.layout.AbsoluteLayout //絕對定位布局 40 >.Ext.layout.FormLayout //表單布局 41 >.Ext.layout.BorderLayout //邊框布局 42 >.Ext.layout.ColumnLayout //分列布局 43 >.Ext.layout.FitLayout //自適應布局 44 >.Ext.layout.Accordion //折疊布局 45 >.Ext.layout.CardLayout //卡片布局 46 >.Ext.layout.TableLayout //表格布局
6.2 最簡單的布局--FitLayout
1 6.2 最簡單的布局--FitLayout 2 //自動適應頁面大小 3 Ext.onReady(function(){ 4 var store = new Ext.data.ArrayStore({ 5 fields:['id','name','desc'], 6 data:[['1','name1','desc1']] //數據存儲器; 7 }); 8 9 var grid = new Ext.grid.GridPanel({ //創建帶數據的表格; 10 title:'grid', 11 viewConfig:{forceFit:true}, 12 store:store, 13 columns:[ 14 {header:'id',dataIndex:'id'}, 15 {header:'名稱',dataIndex:'name'}, 16 {header:'描述',dataIndex:'desc'} 17 ], 18 tbar:new Ext.Toolbar(['添加','修改','刪除']), 19 bbar:new Ext.PagingToolbar({ 20 pageSize:15, 21 store:store 22 }) 23 }); 24 25 var viewport = new Ext.Viewport({ 26 layout:'fit', //指向自適應布局; 27 items:[grid] //將表格引入布局; 28 }); 29 });
6.3 常用的邊框布局--BorderLayout
1 6.3 常用的邊框布局--BorderLayout 2 //FitLayout每次只能使用一個子組件;而現實中我們使用最多的是Ext.layout.BorderLayout布局; 3 var viewport = new Ext.Viewport({ 4 layout:'border', //指向為BorderLayout布局; 5 items:[ 6 {region:'north',html:'north',height:120}, //region:指定組件的位置;html:組件內容; 7 {region:'south',html:'south',height:30}, 8 {region:'west',html:'west',width:40}, 9 {region:'east',html:'east',width:100}, 10 {region:'center',html:'center'} //center的大小是其他4個部分設置好之后計算出來的;不可以省略; 11 ] 12 }); 13 14 6.3.1 設置子區域的大小 15 //可以直接設置north與south的高度和west與east的寬度; 16 17 6.3.2 使用split並限制它的的范圍 18 //使用split參數,用戶可以自行拖放來改變某一個區域的大小; 19 //使用minSize和maxSize將限制用戶拖放的范圍; 20 var viewport = new Ext.Viewport({ 21 layout:'border', 22 items:[ 23 {region:'north',html:'north',split:true}, //頂部可以上下拖動改變大小; 24 {region:'west',html:'west',width:100,split:true,minSize:80,maxSize:120}, 25 //左側可以左右拖動改變大小; 但寬度的范圍在80~120之間; 26 {region:'center',html:'center'} 27 ] 28 }); 29 30 6.3.3 子區域的展開和折疊--collapsible 31 //屬性collapsible:true;這個屬性激活了區域折疊功能; 32 //title:'west';折疊區域的標題;必須跟collapsible一起設置; 33 items:[ 34 {region:'north',html:'north',heith:100,title:'頂部',collapsible:true}, 35 ... 36 ]
6.4 制作伸縮菜單布局--Accordion(折疊布局)
1 6.4 制作伸縮菜單布局--Accordion(折疊布局) 2 //BorderLayout布局下嵌套的Accordion布局; 3 var viewport = new Ext.Viewport({ 4 layout:'border', //第一層是BorderLayout布局; 5 items:[{ 6 region:'west', //子組件左側區域; 7 width:200, 8 layout:'accordion', //子組件是Accordion(折疊)布局; 9 split:true, 10 layoutConfig:{ //布局配置信息; 11 titleCollapse:true, //點擊標題也可折疊; 12 animate:true, //折疊動畫; 13 activeOnTop:false //打開的組件是否置頂; 14 }, 15 items:[{ //孫組件;折疊布局; 16 title:'第一欄', 17 html:'第一欄' 18 },{ 19 title:'第二欄', 20 html:'第二欄' 21 }] 22 },{ 23 region:'center', //子組件center區域; 24 html:'center區域' 25 }] 26 });
6.5 實現操作向導的布局--CardLayout
1 6.5 實現操作向導的布局--CardLayout 2 //為CardLayout配置幾個子面板,每次只顯示其中一個; 3 var viewport = new Ext.Viewport({ 4 layout:'border', 5 items:[{ 6 region:'west', 7 id:'wizard', 8 width:200, 9 title:'xx向導', 10 layout:'card', 11 activeItem:0, 12 bodyStyle:'padding:15px', 13 defaults:{ 14 border:false 15 }, 16 bbar:[{ 17 id:'move-prev', 18 text:'上一步', 19 handler:function(){ 20 navHandler(-1); 21 }, 22 disabled:true 23 },'->',{ 24 id:'move-next', 25 text:'下一步', 26 handler:function(){ 27 navHandler(1); 28 }, 29 }], 30 items:[{ 31 id:'card-0', 32 html:'<h1>歡迎使用向導</h1><p>1/3</p>' 33 },{ 34 id:'card-1', 35 html:'<p>2/3</p>' 36 },{ 37 id:'card-2', 38 html:'<p>完成</p>' 39 }] 40 },{ 41 region:'center', 42 split:true, 43 border:true 44 }] 45 }); 46 //設置navHandler函數 (帶注釋!) 47 var navHandler = function(direction){ 48 var wizard = Ext.getCmp('wizard').layout; 49 var prev = Ext.getCmp('move-prev'); 50 var next = Ext.getCmp('move-next'); 51 var activedId = wizard.activeItem.id; 52 if(activeId == 'card-0'){ 53 if(direction == 1){ 54 wizard.setActiveItem(1); 55 prev.setDisabled(false); 56 } 57 }else if(activeId == 'card-1'){ 58 if(direction == -1){ 59 wizard.setActiveItem(0); 60 prev.setDisabled(true); 61 }else{ 62 wizard.setActiveItem(2); 63 next.setDisabled(true); 64 } 65 }else if(activeId == 'card-2'){ 66 if(direction == -1){ 67 wizard.setActiveItem(1); 68 next.setDisabled(false); 69 } 70 } 71 };
6.6 控制位置和大小的布局--AnchorLayout和AbsolluteLayout
1 6.6 控制位置和大小的布局--AnchorLayout和AbsolluteLayout 2 //AnchorLayout提供了靈活的布局方式,既可以為items中的每個組件指定與總體布局大小的差值;也可以設置一個比例使子組件可以根據整體自行計算本身的大小; 3 >1.使用百分比進行配置 4 //設置某一個子組件占整體長和寬的百分比; 5 var viewport = new Ext.Viewport({ 6 layout:'anchor', //設置接下來的子組件都為AnchorLayout布局; 7 items:[{ 8 title:'panel1', 9 html:'panel1', 10 anchor:'50% 50%' //panel1組件占總體寬度的50%和高度的50%; 11 },{ 12 title:'panel2', 13 html:'panel2', 14 anchor:'80%' //panel2組件占總體寬度的80%,高度自適應; 15 }] 16 }); 17 >2.設置與右側和底部的邊距; 18 var viewport = new Ext.Viewport({ 19 layout:'anchor', 20 items:[{ 21 title:'panel1', 22 html:'panel1', 23 anchor:'-50 -200' //組件與右側和底部的相對(絕對)距離; 24 },{ 25 title:'panel2', 26 html:'panel2', 27 anchor:'-100' //組件與右側的距離; 28 }] 29 }); 30 >3.side布局; 31 //在設置父組件和布局內部子組件都設置好width/height和anchorSize屬性的前提下;AnchorLayout會記錄布局整體與子組件在大小上的差值,為以后調整布局提供依據; 32 var viewport = new Ext.Viewport({ 33 layout:'anchor', 34 anchorSize:{width:400,height:300}, 35 //這是一個包含寬度和高度信息的JSON對象;以此作為以后計算差值的基准; 36 items:[{ 37 title:'panel1', 38 html:'panel1', 39 width:200, 40 height:100, 41 anchor:'r b' 42 },{ 43 title:'panel2', 44 html:'panel2', 45 width:100, 46 height:200, 47 anchor:'r b' 48 }] 49 }); 50 //AnchorLayout首先獲得父組件的寬度/高度,以及每個子組件的寬度/高度,然后將子組件與父組件的寬度/高度之差分別保存起來;根據改變后父組件的大小,計算出子組件當前的寬度和高度; 51 >4.同時使用百分比和邊距 52 var viewport = new Ext.Viewport({ 53 layout:'anchor', 54 items:[{ 55 title:'panel1', 56 html:'panel1', 57 anchor:'-100 40%' //組件距右側100px不變,高度是整體的40%; 58 },{ 59 title:'panel2', 60 html:'panel2', 61 anchor:'-200 60%' //同上; 62 }] 63 }); 64 >5.利用AbsoluteLayout進行絕對定位 65 //AbsoluteLayout是AnchorLayout的一個子類;繼承了AnchorLayout的所有特性; 66 //AnchorLayout布局下的子組件都是自上而下豎直排列的;而AbsoluteLayout正是可以解決這個問題; 67 var viewport = new Ext.Viewport({ 68 layout:'absolute', 69 //以下組件進行絕對定位;並使用AnchorLayout確定每個組件的相對大小; 70 items:[{ 71 title:'panel1', 72 html:'panel1', 73 x:50, //子組件左上角距父組件的距離; 74 y:0, 75 anchor:'-200 40%' //子組件相對於父組件的大小; 76 }] 77 });
6.7 表單專用的布局--FormLayout
1 6.7 表單專用的布局--FormLayout 2 var viewport = new Ext.Viewport({ 3 layout:'fit', //組件自適應填滿布局; 4 items:[{ 5 xtype:'form', 6 title:'信息', 7 labelAlign:'right', //控件標簽右對齊; 8 labelWidth:50, //控件寬度; 9 frame:true, //圓角; 10 defaultType:'textfield',//以下組件為文本框控件; 11 items:[{ 12 fieldLabel:'名稱', 13 name:'name', 14 anchor:'90%' //占整體90%的空間; 15 },{ 16 fieldLabel:'生日', 17 name:'birthday', 18 xtype:'datefield', //日期控件; 19 anchor:'90%' 20 },{ 21 fieldLabel:'備注', 22 name:'desc', 23 xtype:'textarea', //多行文本控件; 24 anchor:'90% -100' //占整體90%;並且距離底部100px; 25 }] 26 }] 27 });
6.8 分列布局--ColumnLayout
1 6.8 分列布局--ColumnLayout 2 //ColumnLayout是將整個容器進行豎直切分的布局方式; 3 >1.使用ColumnLayout實現簡單布局 4 var viewport = new Ext.Viewport({ 5 layout:'column', //分列布局; 6 items:[{ 7 title:'Column1', 8 columnWidth:.25 9 },{ 10 title:'Column2', 11 columnWidth:.4 12 },{ 13 title:'Column3', 14 columnWidth:.35 15 }] 16 }); 17 >2.使用columnWidth平分剩余的寬度 18 var view = new Ext.Viewport({ 19 layout:'column', 20 items:[{ 21 title:'1', 22 width:20 //組件一寬度不變; 23 },{ 24 title:'2', 25 columnWidth:.7 //寬度為剩下的70%; 26 },{ 27 title:'3', 28 columnWidth:.3 29 }] 30 });
6.9 表格狀布局--TableLayout
1 6.9 表格狀布局--TableLayout 2 var view = new Ext.Viewport({ 3 layout:'fit', 4 items:[{ 5 title:'Table Layout', 6 layout:'table', //表格布局; 7 default:{ 8 bodyStyle:'padding:20px' 9 }, 10 layoutConfig:{ 11 columns:3 12 }, 13 items:[{ 14 html:'<p>A</p>', 15 rowspan:2 //合並的行數; 16 },{ 17 html:'<p>B</p>', 18 colspan:2 //合並的列數; 19 },{ 20 html:'<p>C</p>', 21 cellId:'haha' //設置單元格ID; 22 },{ 23 html:'<p>D</p>' 24 }] 25 }] 26 });
6.10 BoxLayout--HBox
1 6.10 BoxLayout--HBox 2 //橫排一行多個組件; 3 var panel = new Ext.Panel({ 4 title:'HBox', 5 width:400, 6 height:200, 7 renderTo:'grid', 8 layout:{ 9 type:'hbox', //指定當前的Panel使用HBox布局方式; 10 padding:'5', 11 align:'stretch' //為組件設置統一的對齊方式;自動充滿外部容器的大小; 12 }, 13 defaults:{margins:'0 0 5 0 '}, 14 items:[{ 15 xtype:'button', //按鈕組件; 16 text:'Button1', 17 flex:1 18 },{ 19 xtype:'button', 20 text:'Button2', 21 flex:3 //值越大,對應的組件占據的空間越大; 22 }] 23 });
6.11 BoxLayout--VBox
1 6.11 BoxLayout--VBox 2 //豎排一列多個組件; 3 var panel = new Ext.Panel({ 4 .. 5 layout:{ 6 type:'vbox', //指定當前的Panel使用HBox布局方式; 7 padding:'5', 8 align:'stretch' 9 }, 10 items:[...] 11 });
6.12 Ext.TabPanel
1 6.12 Ext.TabPanel 2 //Tab布局組件 3 >1.普通Tab 4 var tabs = new Ext.TabPanel({ //創建TabPanel對象; 5 renderTo:document.body, //渲染到指定位置; 6 height:100 7 }); 8 //任意組件直接使用add()函數便可添加到Ext.TabPanel中; 9 tabs.add({ //若不特別指定xtype,就會默認使用Ext.Panel為這些內容生成子面板; 10 id:Ext.id(), //使用Ext.id()函數生成唯一的id值; 11 title:'標題2', 12 html:'內容2', 13 closable:true //生成的標簽受否可以手動關閉; 14 }); 15 tabs.activate(0); //讓指定的標簽變成激活狀態;參數是標簽的索引值; 16 17 >2.添加創建的Tab按鈕 18 //添加兩個按鈕,用於新建包含表格的標簽和包含Panel的標簽 19 var tabs = new Ext.TabPanel({ 20 height:200, 21 renderTo:'tab', 22 enableTabScroll:true 23 }); 24 tabs.add({ 25 title:'標題一', 26 html:'內容一', 27 closable:true 28 }); 29 tabs.setActiveTab(0); 30 31 var addGrid = new Ext.Button({ //創建按鈕; 32 text:'添加一個grid', 33 renderTo:'add-grid', 34 handler:function(){ //"新建"按鈕回調函數; 35 var id = Ext.id(); 36 //創建表格↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 37 var grid = new Ext.grid.GridPanel({ 38 store:new Ext.data.SimpleStore({ 39 fields:['id','name'], 40 data:[ 41 ['1','name1'], 42 ['2','name2'], 43 ] 44 }), 45 columns:[ 46 {header:'序號',dataIndex:'id'}, 47 {header:'名稱',dataIndex:'name'} 48 ] 49 }); 50 //將表格組件放入到tabs里↓↓↓↓ 51 var tab = tabs.add({ 52 title:'表格'+id, 53 closable:true, 54 layout:'fit', 55 items:[grid] 56 }); 57 //激活當前的tab標簽↓↓↓↓ 58 tabs.setActiveTab(tab); 59 } 60 }); 61 62 var addPanel = new Ext.Button({ 63 text:'添加一個panel', 64 renderTo:'add-panel', 65 handler:function(){ 66 var id = Ext.id(); 67 var panel = new Ext.Panel({ //創建Panel標簽; 68 html:'創建Panel標簽成功' 69 }); 70 var tab2 = tabs.add({ 71 title:'Panel'+id, 72 closable:true, 73 layout:'fit', 74 items:[panel] 75 }); 76 tabs.setActiveTab(tab2); 77 } 78 }); 79 80 >3.執行從后台得到的HTML(包含JS腳本) 81 tabs.add({ 82 title:'從后台獲取內容', 83 autoLoad:{url:'xxx.html',scripts:true} 84 //autoLoad:創建后自動執行;默認是延遲加載的; 85 //scripts:執行得到的HTML里的腳本; 86 }) 87 88 6.12.1 標簽面板的滾動菜單 89 //TabPanel的組件,可以在標簽過多的時候顯示一個下拉菜單; 90 //需引入tabs下的TabScrollMenu.js和TabScrollMenu.css; 91 var scrollerMenu = new Ext.ux.TabScrollerMenu({ 92 maxText:15, 93 pageSize:5 94 }); 95 var tabs = new Ext.TabPanel({ 96 width:400, 97 height:200, 98 activeTab:0, 99 enableTabScroll:true, 100 resizeTabs:true, 101 minTabWidth:75, 102 frame:true, 103 plugins:[srcrooerMenu], //標簽過多時顯示下拉菜單; 104 items:[{title:'第一個tab'}], 105 renderTo:'tabs' 106 });
6.13 與布局相關的知識
1 6.13 與布局相關的知識 2 6.13.1 超類Ext.Container的公共配置與xtype的概念 3 >1.Ext.Container是所有可布局組件的超類;只要繼承它的子類都可以對自身進行布局; 4 >2.主要參數: 5 >.layout(組件布局方式); 6 >.items(包含的子組件); 7 >3.與上面對應的還有兩個參數: 8 >.layoutConfig:為布局提供特定的配置參數; 9 //在實例化過程中當前類會把自身的layoutConfig參數賦予layout對象並進行配置; 10 >.activeItem:表示當前顯示哪一個子組件; 11 4.defaultType參數 12 >.當子組件沒有指定xtype參數時,就會使用上級組建中設置的defaultType來作為自身的xtype; 13 //默認情況下是defaultType:'panel',也就是在items中創建的每個子組件都是Ext.Panel的實例; 14 //若需要其他類型的組件,直接替換成對應的類型的值即可; 15 5.xtype 16 //在Ext中,xtype:'grid'和new Ext.grid.GridPanel()是等價的; 17 items:[{ 18 xtype:'grid', 19 store:store, 20 columns:columns 21 }] 22 //整體布局時,使用xtype更方便,結構也更清晰; 23 items:[new Ext.grid.GridPanel({ 24 store:store, 25 columns:columns 26 })] 27 //創建實例的方式更適用於需要對某一部分進行詳細配置的情況; 28 29 6.13.2 layout的超類Ext.layout.ContainerLayout 30 //當layout:'auto'時,就表示將使用Ext.layout.ContainerLayout的布局; 31 32 6.13.3 不指定任何布局時會發生的情況 33 >.組件默認使用的布局類型 34 Ext.Container Ext.layout.ContainerLayout 35 Ext.Viewport Ext.layout.ContainerLayout 36 Ext.Panel Ext.layout.ContainerLayout 37 Ext.TabPanel Ext.layout.CardLayout 38 Ext.Tip Ext.layout.ContainerLayout 39 Ext.Window Ext.layout.ContainerLayout 40 Ext.form.FieldSet Ext.layout.FormPanel 41 Ext.form.FormPanel Ext.layout.FormPanel 42 Ext.tree.TreePanel Ext.layout.ContainerLayout 43 Ext.grid.GridPanel Ext.layout.ContainerLayout 44 Ext.grid.EditorGridPanel Ext.layout.ContainerLayout 45 Ext.grid.PropertyPanel Ext.layout.ContainerLayout 46 47 6.13.4 使用Viewport對整個頁面進行布局 48 //以上示例中,都是用Ext.Viewport對整個頁面進行統一布局; 49 //實際上,Viewport只是一個用於整頁布局的快捷工具類; 50 //多個Viewport之間會沖突; 51 52 6.13.5 使用嵌套實現復雜布局 53 Ext.onReady(function(){ 54 55 //表格配置 56 var columns = [ 57 {header:'編號',dataIndex:'id'}, 58 {header:'名稱',dataIndex:'name'}, 59 {header:'描述',dataIndex:'descn'} 60 ]; 61 var data = [ 62 ['1','name1','descn1'], 63 ['2','name2','descn2'] 64 ]; 65 var store = new Ext.data.ArrayStore({ 66 data:data, 67 fields:[ 68 {name:'id'}, 69 {name:'name'}, 70 {name:'descn'} 71 ] 72 }); 73 store.load(); 74 var grid = new Ext.grid.GridPanel({ 75 store:store, 76 columns:columns, 77 title:'center-north', 78 region:'north' //此表格會在Panel布局的上方; 79 }); 80 81 //樹形配置 82 var tree = new Ext.tree.TreePanel({ 83 store:new Ext.data.TreeStore({ 84 proxy:{ 85 type:'ajax', 86 url:'xxx.html' 87 }, 88 root:{ 89 expand:true, 90 text:'我是根' 91 } 92 }), 93 title:'west', 94 region:'west', //此樹形組件會在Panel布局的左側; 95 split:true, 96 border:true, 97 collapsible:true, 98 width:120, 99 minSize:80, 100 maxSize:200 101 }); 102 103 //表單配置 104 var form = new Ext.form.FormPanel({ 105 defaultType:'textfield', 106 labelAlign:'right', 107 title:'form', 108 labelWidth:50, 109 frame:true, 110 width:220, 111 title:'center-center', 112 region:'center', //此表單組件會在Panel布局的中間; 113 items:[{ 114 fieldLabel:'文本框', 115 anchor:'90%' 116 }], 117 button:[{ 118 text:'按鈕' 119 }] 120 }); 121 122 //布局開始 123 var viewport = new Ext.Viewport({ 124 layout:'border', 125 items:[{ 126 region:'north', 127 contentEl:'north-div', //上布局為id='north-div'的DIV;通過contentEl來指定HTML中顯示的內容; 128 heith:80, 129 bodyStyle:'background-color:#BBCCEE;' 130 },{ 131 region:'south', //下布局為id='south-div'的DIV 132 contentEl:'south-div', 133 height:20, 134 bodyStyle:'background-color:#BBCCEE;' 135 },tree,{ //左側布局;樹形; 136 region:'center', //中間布局; 137 split:true, 138 border:true, 139 layout:'border', //中間區域使用邊界布局; 140 items:[gird,form] //將准備好的表格和表單引入中間布局區域; 141 }] 142 }); 143 }); 144 <div id='north-div'>標題欄:viewport加panel實現復雜布局</div> 145 <div id='south-div'>狀態欄:Copyright by www.xxx.com</div> 146 147 //這個Viewport中的每個子組件都是Panel類型;而Panel包含:TreePanel/GridPanel/FormPanel 148 //所以Panel的配置參數它們也都可以用; 149 //在任何一個Panel里設置layout:'border',就可以將它再次分成5各區域;並用region參數指定各自所在位置; 150 Viewport Panel 151 north:north-div; 152 south:south-div; 153 west:tree; 154 center:Panel; 155 north:grid; 156 center:form;