• EXTJS组件化(三)----组件之间的暧昧关系



    我忽然发现,菜鸟更愿意与人分享他的学习成果.

        在开发过程中,当许多小组件拼合成一个大组件之后,最先遇到的问题就是组件与组件之间的通信和数据交互.

        如果你的组件封装的比较死(即在创建的时候不需要配置属性).则可以通过组建的自定义事件来完成组件与组件之间的项目调用.下面的界面其实没有必要这么做,这么做的目的只是为了解释一下组件与组件之间相互交互数据:
    Js代码  收藏代码
    1. //Panel1和Panel2为视图组件,Main为容器组件  
    2. Ext.namespace("Lesson2.Panel1");  
    3. /** 
    4.  * @author andy_ghg 
    5.  * @version 2009年10月17日1:36:26 
    6.  * @description 组件之间的数据交互(Grid) 
    7.  * @class Lesson2.Panel1 
    8.  * @extends Ext.Panel 
    9.  */  
    10. Lesson2.Panel1 = Ext.extend(Ext.Panel,{  
    11.     layout:"fit",  
    12.     height:200,  
    13.     //初始化函数  
    14.     initComponent : function(){  
    15.         Lesson2.Panel1.superclass.initComponent.call(this,arguments);  
    16.         this.addEvents("gridRowSelected");  
    17.         this.gridStore = new Ext.data.JsonStore({  
    18.             url:"",  
    19.             fields:["xx","yy"],  
    20.             totalPropery:"results",  
    21.             root:"items"  
    22.         });  
    23.         this.gridSm = new Ext.grid.CheckboxSelectionModel();  
    24.           
    25.         this.gridCm = new Ext.grid.ColumnModel([this.gridSm,{  
    26.             header:"列一",  
    27.             dataIndex:"xx"  
    28.         },{  
    29.             header:"列二",  
    30.             dataIndex:"yy"  
    31.         }]);  
    32.           
    33.         this.gridPanel = new Ext.grid.GridPanel({  
    34.             sm:this.gridSm,  
    35.             cm:this.gridCm,  
    36.             store:this.gridStore,  
    37.             viewConfig:{  
    38.                 autoFill:true,  
    39.                 forceFit:true  
    40.             }  
    41.         });  
    42.         this.gridPanel.on("rowclick",this.rowSelect,this);  
    43.         this.add(this.gridPanel);  
    44.     },  
    45.     //提供给外部调用的函数,返回其内部的store  
    46.     getStore:function(){  
    47.         return this.gridPanel.getStore();  
    48.     },  
    49.     rowSelect:function(grid,index,e){  
    50.         var record = grid.getStore().getAt(index);  
    51.         this.fireEvent("gridRowSelected",record);  
    52.     }  
    53. });  
    54. Ext.namespace("Lesson2.Panel2");  
    55. /** 
    56.  * @description 组件之间的相互交互(formPanel) 
    57.  * @class Lesson2.Panel2 
    58.  * @extends Ext.Panel 
    59.  */  
    60. Lesson2.Panel2 = Ext.extend(Ext.Panel,{  
    61.     layout:"fit",  
    62.     frame:true,  
    63.     initComponent:function(){  
    64.         Lesson2.Panel2.superclass.initComponent.call(this,arguments);  
    65.         this.addEvents("addRecord");  
    66.         this.formPanel = new Ext.FormPanel({  
    67.             defaults:{anchor:"95%"},  
    68.             defaultType:"textfield",  
    69.             labelWidth:55,  
    70.             items:[{  
    71.                 fieldLabel:"XXXXX",  
    72.                 name:"xx"  
    73.             },{  
    74.                 fieldLabel:"YYYYY",  
    75.                 name:"yy"  
    76.             }]  
    77.         });  
    78.         this.add(this.formPanel);  
    79.         this.addButton("加入",this.addRecord,this);  
    80.     },  
    81.     //触发自定义事件,并向事件中传递一个参数values  
    82.     addRecord:function(){  
    83.         var values = this.formPanel.getForm().getValues();  
    84.         this.fireEvent("addRecord",values);  
    85.     }  
    86. });  
    87.   
    88. Ext.namespace("Lesson2.Main");  
    89. /** 
    90.  * @description 用于将两个子组件拼合在一起的容器 
    91.  * @class Lesson2.Main 
    92.  * @extends Ext.Panel 
    93.  */  
    94. Lesson2.Main = Ext.extend(Ext.Panel,{  
    95.     renderTo:Ext.getBody(),  
    96.     layout:"form",  
    97.     initComponent:function(){  
    98.         Lesson2.Main.superclass.initComponent.call(this,arguments);  
    99.         this.panel1 = new Lesson2.Panel1();  
    100.         this.panel2 = new Lesson2.Panel2();  
    101.         //在这里捕获panel2的自定义事件  
    102.         this.panel2.on("addRecord",this.addRecordToGrid,this);  
    103.         this.panel1.on("gridRowSelected",this.addRecordToForm,this);  
    104.         //将两个组件加入到视图中去  
    105.         this.add(this.panel1);  
    106.         this.add(this.panel2);  
    107.     },  
    108.     //TODO panel2的事件处理函数,在这里的this代表Lesson2.Main  
    109.     //这里通过this获取panel1的实例,再通过panel1的实例调用panel1的方法getStore()  
    110.     //panel1的getStore()函数会返回其内部的gridPanel的Store  
    111.     //参数的values就是panel2触发了自定义事件后传递进来的  
    112.     addRecordToGrid:function(values){  
    113.         var record = new Ext.data.Record(values);  
    114.         this.panel1.getStore().add(record);  
    115.     },  
    116.     //TODO 第二种方法,直接获取panel1里的store,效果是一样的  
    117.     addRecordToGrid_2:function(values){  
    118.         var record = new Ext.data.Record(values);  
    119.         this.panel1.gridStore.add(record);  
    120.     },  
    121.     //TODO panel1的事件处理函数,在这里会获取到panel2的实例,并通过该实例获取其内部的formPanel并调用  
    122.     //formPanel的相应方法来达到读取数据的目的  
    123.     addRecordToForm:function(record){  
    124.         this.panel2.formPanel.getForm().loadRecord(record);  
    125.     }  
    126. });  
    127. Ext.onReady(function(){  
    128.     var ls = new Lesson2.Main({  
    129.         title:"测试",  
    130.         400  
    131.     });  
    132. });  


        如果你的组件封装的比较灵活,则可以在容器内就直接调用容器中的方法进行操作,比如上面的代码稍微修改一下(注意panel2的Button):
    Js代码  收藏代码
    1. Ext.namespace("Lesson2.Panel1");  
    2. /** 
    3.  * @author andy_ghg 
    4.  * @version 2009年10月17日1:36:26 
    5.  * @description 组件之间的数据交互(Grid) 
    6.  * @class Lesson2.Panel1 
    7.  * @extends Ext.Panel 
    8.  */  
    9. Lesson2.Panel1 = Ext.extend(Ext.Panel,{  
    10.     layout:"fit",  
    11.     height:200,  
    12.     //初始化函数  
    13.     initComponent : function(){  
    14.         Lesson2.Panel1.superclass.initComponent.call(this,arguments);  
    15.         this.addEvents("gridRowSelected");  
    16.         this.gridStore = new Ext.data.JsonStore({  
    17.             url:"",  
    18.             fields:["xx","yy"],  
    19.             totalPropery:"results",  
    20.             root:"items"  
    21.         });  
    22.         this.gridSm = new Ext.grid.CheckboxSelectionModel();  
    23.           
    24.         this.gridCm = new Ext.grid.ColumnModel([this.gridSm,{  
    25.             header:"列一",  
    26.             dataIndex:"xx"  
    27.         },{  
    28.             header:"列二",  
    29.             dataIndex:"yy"  
    30.         }]);  
    31.           
    32.         this.gridPanel = new Ext.grid.GridPanel({  
    33.             sm:this.gridSm,  
    34.             cm:this.gridCm,  
    35.             store:this.gridStore,  
    36.             viewConfig:{  
    37.                 autoFill:true,  
    38.                 forceFit:true  
    39.             }  
    40.         });  
    41.         this.gridPanel.on("rowclick",this.rowSelect,this);  
    42.         this.add(this.gridPanel);  
    43.     },  
    44.     //提供给外部调用的函数,返回其内部的store  
    45.     getStore:function(){  
    46.         return this.gridPanel.getStore();  
    47.     },  
    48.     rowSelect:function(grid,index,e){  
    49.         var record = grid.getStore().getAt(index);  
    50.         this.fireEvent("gridRowSelected",record);  
    51.     }  
    52. });  
    53. Ext.namespace("Lesson2.Panel2");  
    54. /** 
    55.  * @description 组件之间的相互交互(formPanel) 
    56.  * @class Lesson2.Panel2 
    57.  * @extends Ext.Panel 
    58.  */  
    59. Lesson2.Panel2 = Ext.extend(Ext.Panel,{  
    60.     layout:"fit",  
    61.     frame:true,  
    62.     initComponent:function(){  
    63.         Lesson2.Panel2.superclass.initComponent.call(this,arguments);  
    64.         this.formPanel = new Ext.FormPanel({  
    65.             defaults:{anchor:"95%"},  
    66.             defaultType:"textfield",  
    67.             labelWidth:55,  
    68.             items:[{  
    69.                 fieldLabel:"XXXXX",  
    70.                 name:"xx"  
    71.             },{  
    72.                 fieldLabel:"YYYYY",  
    73.                 name:"yy"  
    74.             }]  
    75.         });  
    76.         this.add(this.formPanel);  
    77.     }  
    78. });  
    79.   
    80. Ext.namespace("Lesson2.Main");  
    81. /** 
    82.  * @description 用于将两个子组件拼合在一起的容器 
    83.  * @class Lesson2.Main 
    84.  * @extends Ext.Panel 
    85.  */  
    86. Lesson2.Main = Ext.extend(Ext.Panel,{  
    87.     renderTo:Ext.getBody(),  
    88.     layout:"form",  
    89.     initComponent:function(){  
    90.         Lesson2.Main.superclass.initComponent.call(this,arguments);  
    91.         this.panel1 = new Lesson2.Panel1();  
    92.         this.panel2 = new Lesson2.Panel2({  
    93.             buttons:[{  
    94.                 text:"确定",  
    95.                 handler:this.addRecordToGrid_2,  
    96.                 scope:this  
    97.             }]  
    98.         });  
    99.         //在这里捕获panel2的自定义事件  
    100.         this.panel1.on("gridRowSelected",this.addRecordToForm,this);  
    101.         //将两个组件加入到视图中去  
    102.         this.add(this.panel1);  
    103.         this.add(this.panel2);  
    104.     },  
    105.     //这里直接就获取当前容器的子组件panel2并获取panel2中的formPanel进行操作  
    106.     addRecordToGrid_2:function(){  
    107.         var values = this.panel2.formPanel.getForm().getValues();  
    108.         var record = new Ext.data.Record(values);  
    109.         this.panel1.gridStore.add(record);  
    110.     },  
    111.     //TODO panel1的事件处理函数,在这里会获取到panel2的实例,并通过该实例获取其内部的formPanel并调用  
    112.     //formPanel的相应方法来达到读取数据的目的  
    113.     addRecordToForm:function(record){  
    114.         this.panel2.formPanel.getForm().loadRecord(record);  
    115.     }  
    116. });  
    117. Ext.onReady(function(){  
    118.     var ls = new Lesson2.Main({  
    119.         title:"测试",  
    120.         400  
    121.     });  
    122. });  


        两种写法有各自的好处.看大家怎么取舍了,当然,组件和组件之间的交互远不只这些简单的操作,还包括当一个组件还未被创建,而另外一个组件已经向这个组件发送数据等等,这些就要考虑使用一个第三方的数据组件来做中转.Extjs的StoreMgr可以做到,你也可以自己写一个符合你自己要求的数据组件,可以模仿StoreMgr写一个.
  • 相关阅读:
    JavaScript变量存储浅析
    AngularJS学习篇(二十二)
    css目录
    html目录
    javascript目录
    第一篇 dom
    第五篇、css补充二
    第六篇 javascript面向对象
    第三篇 css属性
    jmeter之-图形监控
  • 原文地址:https://www.cnblogs.com/sunscheung/p/4839406.html
Copyright © 2020-2023  润新知