Ext的window布局

 

Window

 复习一下,先来构造一个Window对象:

Js代码 复制代码
  1. Ext.onReady(function(){   
  2.     var _window=new Ext.Window({   
  3.         title:"New Person",   
  4.         width:500,   
  5.         height:100,   
  6.         plain:true,   
  7.         items:[   
  8.             {}   
  9.         ],   
  10.         buttons:[   
  11.             {text:"OK"},   
  12.             {text:"Cancel"}   
  13.         ]   
  14.     });   
  15.     _window.show();   
  16. });  

 

和Panel很像吧,items:[{}],如果没有指定defaultType,items中默认就是Panel类型

 

这时Panel的背景是白色,想要背景色和外面的Container统一,首先想到了Plain这个构造参数,但是看API中的Panel定义是没有Plain的,它提供了另外一种方式 baseCls ,

Js代码 复制代码
  1. items:[   
  2.     {baseCls:"x-plain"}   
  3. ],  

 

指定baseCls值为“x-plain”,效果:

 

这样Panel的背景色和外部的Container就统一了

 

这样一个Window对象就构建成功了,但是Window对象里面什么也没有,往Window里面加一些内容。

 

 

列布局

Window中的Button:

   Buttons 在Window是比较特殊的布局,总是在Window中所有元素的最下方,这里先说一下,Buttons是一组Button元素的集合,它的取值使用前面谈到的向下索引的方式可以实现:

Js代码 复制代码
  1. buttons:[   
  2.     {   
  3.         text:"OK",   
  4.         handler:function(){   
  5.             alert(this.ownerCt.buttons[1].text);   
  6.         }   
  7.     },   
  8.     {text:"Cancel"}   
  9. ]  

 

弹出结果是“Cancel”, 是Buttons集合中第二个元素的文本。

 

 

下面来说其他的布局形式,在Window中加上两列:

 

Js代码 复制代码
  1. Ext.onReady(function(){   
  2.     var _window=new Ext.Window({   
  3.         title:"New Person",   
  4.         width:500,   
  5.         height:100,   
  6.         plain:true,   
  7.         items:[{   
  8.             baseCls:"x-plain",   
  9.             layout:"column",   
  10.             items:[{   
  11.                     columnWidth:.5   
  12.                 },   
  13.                 {   
  14.                     columnWidth:.5   
  15.                 }   
  16.             ]   
  17.         }],   
  18.         buttons:[   
  19.             {text:"OK"},   
  20.             {text:"Cancel"}   
  21.         ]   
  22.     });   
  23.     _window.show();   
  24. });  

 

在Window的items构造参数中默认构造出一个Panel对象,Panel中又出现了items构造参数,因为没有设置defaultType,所以items构造出来的还是一个Panel,为这个Panel对象设置布局样式为“column”,按列来进行布局,再在这个Panel的构造参数items中放入两个对象,设置columnWidth属性为“.5”(50%,0.5的缩写,可以省略调前面的0),两个对象各占整行的一半宽度。 

 

 

在左半边的Panel里面添加内容:

Js代码 复制代码
  1. Ext.onReady(function(){   
  2.     var _window=new Ext.Window({   
  3.         title:"New Person",   
  4.         width:500,   
  5.         height:300,   
  6.         plain:true,   
  7.         items:[{   
  8.             baseCls:"x-plain",   
  9.             layout:"column",   
  10.             items:[{   
  11.                     columnWidth:.5,   
  12.                     layout:"form",   
  13.                     defaults:{xtype:"textfield", width:170},   
  14.                     labelWidth:45,   
  15.                     items:[   
  16.                         {fieldLabel:"Name"},   
  17.                         {fieldLabel:"Gender"},   
  18.                         {fieldLabel:"Age"},   
  19.                         {fieldLabel:"Birth"},   
  20.                         {fieldLabel:"Phone"},   
  21.                         {fieldLabel:"Email"}   
  22.                     ]   
  23.                 },   
  24.                 {   
  25.                     columnWidth:.5   
  26.                 }   
  27.             ]   
  28.         }],   
  29.         buttons:[   
  30.             {text:"OK"},   
  31.             {text:"Cancel"}   
  32.         ]   
  33.     });   
  34.     _window.show();   
  35. });  

 

 添加了6个TextField,方法和前面笔记中的一样,只是TextField所在的Panel位置在几个Container的内部,其他的没有变化。效果:


 

使用defaultType:"textfield",可以减少很多的代码量,要是需要统一设置 TextField 的宽度,则使用defaults:{xtype:"textfield", width:170}就可以, 可以同时设置两个:defaultType:"textfield" 和defaults:{width:170},效果是一样的。

 

 再设置一下样式:

Js代码 复制代码
  1. baseCls:"x-plain",   
  2. bodyStyle:"padding-top: 15px; padding-left:10px;",   
  3.                       

 

这样效果就漂亮多了。

 

在右半边的 Panel 中放一个图片作为照片,这里用到 TextField 的另外一个构造参数 inputType:

 

从API中可以看到,通过构造参数inputType,可以设置TextField的类型,就像HTML中的input框一样,可以是:文本框,密码框,单选框,复选框,上传文件的类型还有图片类型等,inputType默认是文本框。

 

来创建一个图片域

 

Js代码 复制代码
  1. {   
  2.     columnWidth:.5,   
  3.     layout:"form",   
  4.     style:"padding:10px",   
  5.     labelWidth:45,   
  6.     baseCls:"x-plain",   
  7.     items:[   
  8.         {   
  9.             xtype:"textfield",    
  10.             inputType:"image",   
  11.             width:150,   
  12.             height:150,   
  13.             fieldLabel:"Photo"  
  14.         }   
  15.     ]   
  16. }  

 


 

看到图片占位符已经存在了,大小样式也比较合适。 

 

要在下面在加上 TextField ,那么就要考虑整体的布局了,实际上我们的布局是这样的


 

在Window下面横向有两个Panel,上面的Panel里面纵向存在两个Panel,左边放置的是一组 TextField,右边放置的是一个图片,下面的Panel里面准备放置另一组 TextField, 这种需求下就应该在Window中做这样的定义

 

Js代码 复制代码
  1. layout:"form",   
  2. defaultType:"textfield",   
  3. labelWidth:55,  

 

外面的defaultType定义成了 TextField,里面就需要强制定义成为Panel的类型:xtype:"panel",此外,要把下面的一组 TextField 定义和上面的放在同一级别中,即第一个 items 构造参数中的数组里面。

 

 

Java代码 复制代码
  1. <script type="text/javascript">   
  2.   
  3.     Ext.onReady(function(){   
  4.         var _window=new Ext.Window({   
  5.             title:"New Person",   
  6.             width:500,   
  7.             height:350,   
  8.             plain:true,   
  9.             layout:"form",   
  10.             defaultType:"textfield",   
  11.             labelWidth:55,   
  12.             items:[{   
  13.                 xtype:"panel",   
  14.                 baseCls:"x-plain",   
  15.                 layout:"column",   
  16.                 items:[{   
  17.                     //中间的两列   
  18.                     }   
  19.                 ]   
  20.             },{   
  21.                 fieldLabel:"ID",   
  22.                 width:"400"  
  23.             },{   
  24.                 fieldLabel:"Address",   
  25.                 width:"400"  
  26.             },{   
  27.                 fieldLabel:"Depart",   
  28.                 width:"400"  
  29.             }],   
  30.             buttons:[   
  31.                 {text:"OK"},   
  32.                 {text:"Cancel"}   
  33.             ]   
  34.         });   
  35.         _window.show();   
  36.     });  
<script type="text/javascript">

	Ext.onReady(function(){
		var _window=new Ext.Window({
			title:"New Person",
			width:500,
			height:350,
			plain:true,
			layout:"form",
			defaultType:"textfield",
			labelWidth:55,
			items:[{
				xtype:"panel",
				baseCls:"x-plain",
				layout:"column",
				items:[{
					//中间的两列
					}
				]
			},{
				fieldLabel:"ID",
				width:"400"
			},{
				fieldLabel:"Address",
				width:"400"
			},{
				fieldLabel:"Depart",
				width:"400"
			}],
			buttons:[
				{text:"OK"},
				{text:"Cancel"}
			]
		});
		_window.show();
	});

 

 

效果是这样: 

 

 

上面的TextField和下面的看起来样式不统一,这里需要调整一下,把样式统一起来。

 

左上部分的LabelWidth是45px,而下半部分的LabelWidth是55px,把它们都统一成45px,并且要删除掉左上部分的CSS的样式,把它的样式定义放到最外层的Panel中,

 

删除掉:

Js代码 复制代码
  1. bodyStyle:"padding-top: 10px; padding-left:10px;",  

 

然后在最外层的Panel中定义:

Js代码 复制代码
  1. var _window=new Ext.Window({   
  2.             title:"New Person",   
  3.             width:500,   
  4.             height:350,   
  5.             plain:true,   
  6.             layout:"form",   
  7.             defaultType:"textfield",   
  8.             labelWidth:45,   
  9.   
  10.             <SPAN style="COLOR: #0000ff">bodyStyle:"padding-top: 10px; padding-left:10px;",</SPAN>   
  11.   
  12.   
  13.             items:[{.......  

 

这样上下的TextField样式就一致了


但是上下两部分中间的间隙比较大,很明显Image部分的高度超过了左半部分,把他的Height属性从150px修改为140px,但是还有一个间隙,因为Image还有设置了CSS的padding属性为10px,也就是上下左右的内间距都是10px,需要把下边的内间距修改为0,他的CSS要这样写:

Js代码 复制代码
  1. style:"padding:10px 10px 0 10px",  

 

顺序是 上 右 下 左,也就是顺时针的方向。

 

在把最外层的Panel的Height属性设置为320px,这下看起来就更舒服了:


接下来,为空白的Photo部分加上图片, 因为我们没有办法直接把一个图像加到里面,所以想到使用“render”,将生成好的Image添加到指定的HTML对象中,这里使用Listeners,注意Listeners添加的位置,还是在最外层的Panel中,在上一篇笔记中说到了Component之间的向上索引和向下索引,这里从最外层的Panel向下索引到Image所在的TextField中间经过了好几层,这样就显得非常的繁琐,好在Ext也想到了这一点,提供了其他的方式来让我们找到目标对象,来试验一下:

 

 

Java代码 复制代码
  1. Ext.onReady(function(){   
  2.     var _window=new Ext.Window({   
  3.         title:"New Person",   
  4.         width:500,   
  5.         height:320,   
  6.         plain:true,   
  7.         layout:"form",   
  8.         defaultType:"textfield",   
  9.         labelWidth:45,   
  10.         bodyStyle:"padding-top: 10px; padding-left:10px;",   
  11.         items:[{   
  12.             ......   
  13.         }],   
  14.   
  15.   
  16.         listeners:{   
  17.             "render":function(_window){   
  18.                         alert(_window.findByType("textfield")[6].fieldLabel);   
  19.                      }   
  20.         },   
  21.   
  22.   
  23.         buttons:[   
  24.             {text:"OK"},   
  25.             {text:"Cancel"}   
  26.         ]   
  27.     });   
  28.     _window.show();   
  29. });  
	Ext.onReady(function(){
		var _window=new Ext.Window({
			title:"New Person",
			width:500,
			height:320,
			plain:true,
			layout:"form",
			defaultType:"textfield",
			labelWidth:45,
			bodyStyle:"padding-top: 10px; padding-left:10px;",
			items:[{
				......
			}],


			listeners:{
				"render":function(_window){
						 	alert(_window.findByType("textfield")[6].fieldLabel);
						 }
			},


			buttons:[
				{text:"OK"},
				{text:"Cancel"}
			]
		});
		_window.show();
	});

 

alert弹出的结果是“photo”,正是要找的Image所在的textfield,

 

findByType,这里的Type是xtype,

 

_window.findByType("textfield")[6] :在最外层的Panel中一共有7个textfield,找到textfield类型的Component并指定它的位置,就索引到了目标对象。

 

但是这个目标对象还不是能放入Image的Dom节点,要把Image放入其中,需要找到相应的Dom节点:

 

Js代码 复制代码
  1. listeners:{   
  2.     "render":function(_window){   
  3.             alert(_window.findByType("textfield")[6].getEl());   
  4.          }   
  5. },  

 

getEl()方法:得到当前Ext组件对象的元素对象 ,得到的是一个Ext的Element。

 

但是这个时候alert弹出的对话框提示undefined,这是为什么呢?

 

在Ext2.0以后,为了提高浮动层(Window实际是一个浮动层)的加载效率,Window组件只有当它执行show()方法的时候才会将里面的组件加载进去 ,而我们使用的“render”事件,是在Window对象构建的时候就要把textfield组件加载进去,实际上这个时候Window组件里面并没有构建textfield,所以会提示Undefined。

 

因此需要注册在Listener里面的不是“render”,而是“show ”。

Js代码 复制代码
  1. listeners:{   
  2.     "show":function(_window){   
  3.             alert(_window.findByType("textfield")[6].getEl());   
  4.          }   
  5. },  

 

这时弹出来的就是预期的“Object”了,

 

现在找到了这个对象只要给出相应的图片链接就可以了

Js代码 复制代码
  1. listeners:{   
  2.     "show":function(_window){   
  3.                 _window.findByType("textfield")[6].getEl().dom.src = "../../../image/default_pic.gif";   
  4.              }   
  5. },  

 

路径问题就不多说了,我的路径是这样的:

效果:

这样就图片就显示成功了,但是这里又有一个问题,图片加载注册到show()方法上,每次Window调用show()方法的时候都会加载图片,效果也不理想,最好是Image随着Window创建只加载一次,当Window调用Hide()方法隐藏后再显示出来就不用再次装载了。

 

解决办法是给Window加上一个自定义属性:

 

Js代码 复制代码
  1. showLock:false,        
  2. listeners:{   
  3.     "show":function(_window){   
  4.                 if(!_window["showLock"]){   
  5.                     _window.findByType("textfield")[6].getEl().dom.src = "../../../image/default_pic.gif";   
  6.                     _window["showLock"]=true;                  
  7.                 }   
  8.              }   
  9. },  

 

这样就可以实现只加载一次的效果了。

 

另外,因为Photo中图片是固定宽度和高度,当拉伸窗体的时候,布局会发生改变,如:

显然这都不是我们期望的效果

 

 

锚点布局

在布局中使用百分比来定义元素的各个属性。

 

 

在window的定义中加上:

Js代码 复制代码
  1. defaults:{anchor:"100%"},  

 

拉长或缩短window,元素都顶边显示,元素宽度会随着窗体的改变而改变,原来定义的固定宽度失效了(Photo并没有改变)。这种可变长的定义是推荐使用的。

 

布局上面的问题还是有很多的,尤其是Ext不同版本实现还是有一定的差别的,在应用的时候要多注意。

 

 

最后附上完整代码:

 

Js代码 复制代码
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">   
  2. <html>   
  3. <head>   
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">   
  5. <title>Window Layout</title>   
  6. <link type="text/css" rel="stylesheet" href="../../../ext/resources/css/ext-all.css">   
  7.   
  8. <script type="text/javascript" src="../../../ext/adapter/ext/ext-base.js"></script>   
  9. <script type="text/javascript" src="../../../ext/ext-all.js"></script>   
  10.   
  11. <script type="text/javascript">   
  12.   
  13.     Ext.onReady(function(){   
  14.         var _window=new Ext.Window({   
  15.             title:"New Person",   
  16.             width:500,   
  17.             height:320,   
  18.             plain:true,   
  19.             layout:"form",   
  20.             defaultType:"textfield",   
  21.             labelWidth:45,   
  22.             bodyStyle:"padding-top: 10px; padding-left:10px;",   
  23.             defaults:{anchor:"100%"},   
  24.             items:[{   
  25.                 xtype:"panel",   
  26.                 baseCls:"x-plain",   
  27.                 layout:"column",   
  28.                 items:[{   
  29.                         columnWidth:.5,   
  30.                         layout:"form",   
  31.                         defaults:{xtype:"textfield", width:170},   
  32.                         labelWidth:45,   
  33.                         baseCls:"x-plain",   
  34.                         /*bodyStyle:"padding-top: 10px; padding-left:10px;",*/  
  35.                         items:[   
  36.                             {fieldLabel:"Name"},   
  37.                             {fieldLabel:"Gender"},   
  38.                             {fieldLabel:"Age"},   
  39.                             {fieldLabel:"Birth"},   
  40.                             {fieldLabel:"Phone"},   
  41.                             {fieldLabel:"Email"}   
  42.                         ]   
  43.                     },   
  44.                     {   
  45.                         columnWidth:.5,   
  46.                         layout:"form",   
  47.                         style:"padding:10px 10px 0 10px",   
  48.                         labelWidth:45,   
  49.                         baseCls:"x-plain",   
  50.                         items:[   
  51.                             {   
  52.                                 xtype:"textfield",    
  53.                                 inputType:"image",   
  54.                                 width:150,   
  55.                                 height:140,   
  56.                                 fieldLabel:"Photo"  
  57.                             }   
  58.                         ]   
  59.                     }   
  60.                 ]   
  61.             },{   
  62.                 fieldLabel:"ID",   
  63.                 width:"400"  
  64.             },{   
  65.                 fieldLabel:"Address",   
  66.                 width:"400"  
  67.             },{   
  68.                 fieldLabel:"Depart",   
  69.                 width:"400"  
  70.             }],   
  71.             showLock:false,        
  72.             listeners:{   
  73.                 "show":function(_window){   
  74.                             if(!_window["showLock"]){   
  75.                                 _window.findByType("textfield")[6].getEl().dom.src = "../../../image/default_pic.gif";   
  76.                                 _window["showLock"]=true;                  
  77.                             }   
  78.                          }   
  79.             },   
  80.             buttons:[   
  81.                 {   
  82.                     text:"OK",   
  83.                     handler:function(){   
  84.                         alert(this.ownerCt.buttons[1].text);   
  85.                     }   
  86.                 },   
  87.                 {text:"Cancel"}   
  88.             ]   
  89.         });   
  90.         _window.show();   
  91.     });   
  92.   
  93. </script>   
  94. </head>   
  95. <body>   
  96.   
  97. </body>   
  98. </html>  
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值