zoukankan      html  css  js  c++  java
  • Ext学习笔记07 Window及Window中的布局

    Window 

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

    Js代码 
    1. Ext.onReady(function(){  
    2.     var _window=new Ext.Window({  
    3.         title:"New Person",  
    4.         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.         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.         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", 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", 170}就可以, 可以同时设置两个:defaultType:"textfield" 和defaults:{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.             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.             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.                 "400"  
    23.             },{  
    24.                 fieldLabel:"Address",  
    25.                 "400"  
    26.             },{  
    27.                 fieldLabel:"Depart",  
    28.                 "400"  
    29.             }],  
    30.             buttons:[  
    31.                 {text:"OK"},  
    32.                 {text:"Cancel"}  
    33.             ]  
    34.         });  
    35.         _window.show();  
    36.     });  

     

     

    效果是这样: 

     

     

    上面的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.             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.         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. });  

     

    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 = "http://www.cnblogs.com/../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 = "http://www.cnblogs.com/../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="http://www.cnblogs.com/../ext/resources/css/ext-all.css">  
    7.   
    8. <script type="text/javascript" src="http://www.cnblogs.com/../ext/adapter/ext/ext-base.js"></script>  
    9. <script type="text/javascript" src="http://www.cnblogs.com/../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.             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", 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.                                 150,  
    55.                                 height:140,  
    56.                                 fieldLabel:"Photo"  
    57.                             }  
    58.                         ]  
    59.                     }  
    60.                 ]  
    61.             },{  
    62.                 fieldLabel:"ID",  
    63.                 "400"  
    64.             },{  
    65.                 fieldLabel:"Address",  
    66.                 "400"  
    67.             },{  
    68.                 fieldLabel:"Depart",  
    69.                 "400"  
    70.             }],  
    71.             showLock:false,       
    72.             listeners:{  
    73.                 "show":function(_window){  
    74.                             if(!_window["showLock"]){  
    75.                                 _window.findByType("textfield")[6].getEl().dom.src = "http://www.cnblogs.com/../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>  

     

  • 相关阅读:
    SQL PASS 北京2013年6月15日活动照片集
    XML约束文档DTD
    内存管理之虚拟页式分配
    设备驱动中异步通知编程
    王家林 云计算分布式大数据Hadoop实战高手之路第七讲Hadoop图文训练课程:通过HDFS的心跳来测试replication具体的工作机制和流程
    安装配置netanalyzer/netsnmp3.5.7_rc1
    理解Java对象序列化——Serializable接口
    世界500强高频逻辑推理智力面试题(二)
    2column left navigation 中遇到的问题
    Visual Studio 2010 无法打开 源 文件 "iostream.h"
  • 原文地址:https://www.cnblogs.com/aaa6818162/p/1936746.html
Copyright © 2011-2022 走看看