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

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

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

如果你的组件封装的比较死(即在创建的时候不需要配置属性).则可以通过组建的自定义事件来完成组件与组件之间的项目调用.下面的界面其实没有必要这么做,这么做的目的只是为了解释一下组件与组件之间相互交互数据:

//Panel1和Panel2为视图组件,Main为容器组件
Ext.namespace("Lesson2.Panel1");
/**
* @author andy_ghg
* @version 2009年10月17日1:36:26
* @description 组件之间的数据交互(Grid)
* @class Lesson2.Panel1
* @extends Ext.Panel
*/
Lesson2.Panel1 = Ext.extend(Ext.Panel,{
layout:"fit",
height:200,
//初始化函数
initComponent : function(){
Lesson2.Panel1.superclass.initComponent.call(this,arguments);
this.addEvents("gridRowSelected");
this.gridStore = new Ext.data.JsonStore({
url:"",
fields:["xx","yy"],
totalPropery:"results",
root:"items"
});
this.gridSm = new Ext.grid.CheckboxSelectionModel();

this.gridCm = new Ext.grid.ColumnModel([this.gridSm,{
header:"列一",
dataIndex:"xx"
},{
header:"列二",
dataIndex:"yy"
}]);

this.gridPanel = new Ext.grid.GridPanel({
sm:this.gridSm,
cm:this.gridCm,
store:this.gridStore,
viewConfig:{
autoFill:true,
forceFit:true
}
});
this.gridPanel.on("rowclick",this.rowSelect,this);
this.add(this.gridPanel);
},
//提供给外部调用的函数,返回其内部的store
getStore:function(){
return this.gridPanel.getStore();
},
rowSelect:function(grid,index,e){
var record = grid.getStore().getAt(index);
this.fireEvent("gridRowSelected",record);
}
});
Ext.namespace("Lesson2.Panel2");
/**
* @description 组件之间的相互交互(formPanel)
* @class Lesson2.Panel2
* @extends Ext.Panel
*/
Lesson2.Panel2 = Ext.extend(Ext.Panel,{
layout:"fit",
frame:true,
initComponent:function(){
Lesson2.Panel2.superclass.initComponent.call(this,arguments);
this.addEvents("addRecord");
this.formPanel = new Ext.FormPanel({
defaults:{anchor:"95%"},
defaultType:"textfield",
labelWidth:55,
items:[{
fieldLabel:"XXXXX",
name:"xx"
},{
fieldLabel:"YYYYY",
name:"yy"
}]
});
this.add(this.formPanel);
this.addButton("加入",this.addRecord,this);
},
//触发自定义事件,并向事件中传递一个参数values
addRecord:function(){
var values = this.formPanel.getForm().getValues();
this.fireEvent("addRecord",values);
}
});

Ext.namespace("Lesson2.Main");
/**
* @description 用于将两个子组件拼合在一起的容器
* @class Lesson2.Main
* @extends Ext.Panel
*/
Lesson2.Main = Ext.extend(Ext.Panel,{
renderTo:Ext.getBody(),
layout:"form",
initComponent:function(){
Lesson2.Main.superclass.initComponent.call(this,arguments);
this.panel1 = new Lesson2.Panel1();
this.panel2 = new Lesson2.Panel2();
//在这里捕获panel2的自定义事件
this.panel2.on("addRecord",this.addRecordToGrid,this);
this.panel1.on("gridRowSelected",this.addRecordToForm,this);
//将两个组件加入到视图中去
this.add(this.panel1);
this.add(this.panel2);
},
//TODO panel2的事件处理函数,在这里的this代表Lesson2.Main
//这里通过this获取panel1的实例,再通过panel1的实例调用panel1的方法getStore()
//panel1的getStore()函数会返回其内部的gridPanel的Store
//参数的values就是panel2触发了自定义事件后传递进来的
addRecordToGrid:function(values){
var record = new Ext.data.Record(values);
this.panel1.getStore().add(record);
},
//TODO 第二种方法,直接获取panel1里的store,效果是一样的
addRecordToGrid_2:function(values){
var record = new Ext.data.Record(values);
this.panel1.gridStore.add(record);
},
//TODO panel1的事件处理函数,在这里会获取到panel2的实例,并通过该实例获取其内部的formPanel并调用
//formPanel的相应方法来达到读取数据的目的
addRecordToForm:function(record){
this.panel2.formPanel.getForm().loadRecord(record);
}
});
Ext.onReady(function(){
var ls = new Lesson2.Main({
title:"测试",
width:400
});
});


如果你的组件封装的比较灵活,则可以在容器内就直接调用容器中的方法进行操作,比如上面的代码稍微修改一下(注意panel2的Button):

Ext.namespace("Lesson2.Panel1");
/**
* @author andy_ghg
* @version 2009年10月17日1:36:26
* @description 组件之间的数据交互(Grid)
* @class Lesson2.Panel1
* @extends Ext.Panel
*/
Lesson2.Panel1 = Ext.extend(Ext.Panel,{
layout:"fit",
height:200,
//初始化函数
initComponent : function(){
Lesson2.Panel1.superclass.initComponent.call(this,arguments);
this.addEvents("gridRowSelected");
this.gridStore = new Ext.data.JsonStore({
url:"",
fields:["xx","yy"],
totalPropery:"results",
root:"items"
});
this.gridSm = new Ext.grid.CheckboxSelectionModel();

this.gridCm = new Ext.grid.ColumnModel([this.gridSm,{
header:"列一",
dataIndex:"xx"
},{
header:"列二",
dataIndex:"yy"
}]);

this.gridPanel = new Ext.grid.GridPanel({
sm:this.gridSm,
cm:this.gridCm,
store:this.gridStore,
viewConfig:{
autoFill:true,
forceFit:true
}
});
this.gridPanel.on("rowclick",this.rowSelect,this);
this.add(this.gridPanel);
},
//提供给外部调用的函数,返回其内部的store
getStore:function(){
return this.gridPanel.getStore();
},
rowSelect:function(grid,index,e){
var record = grid.getStore().getAt(index);
this.fireEvent("gridRowSelected",record);
}
});
Ext.namespace("Lesson2.Panel2");
/**
* @description 组件之间的相互交互(formPanel)
* @class Lesson2.Panel2
* @extends Ext.Panel
*/
Lesson2.Panel2 = Ext.extend(Ext.Panel,{
layout:"fit",
frame:true,
initComponent:function(){
Lesson2.Panel2.superclass.initComponent.call(this,arguments);
this.formPanel = new Ext.FormPanel({
defaults:{anchor:"95%"},
defaultType:"textfield",
labelWidth:55,
items:[{
fieldLabel:"XXXXX",
name:"xx"
},{
fieldLabel:"YYYYY",
name:"yy"
}]
});
this.add(this.formPanel);
}
});

Ext.namespace("Lesson2.Main");
/**
* @description 用于将两个子组件拼合在一起的容器
* @class Lesson2.Main
* @extends Ext.Panel
*/
Lesson2.Main = Ext.extend(Ext.Panel,{
renderTo:Ext.getBody(),
layout:"form",
initComponent:function(){
Lesson2.Main.superclass.initComponent.call(this,arguments);
this.panel1 = new Lesson2.Panel1();
this.panel2 = new Lesson2.Panel2({
buttons:[{
text:"确定",
handler:this.addRecordToGrid_2,
scope:this
}]
});
//在这里捕获panel2的自定义事件
this.panel1.on("gridRowSelected",this.addRecordToForm,this);
//将两个组件加入到视图中去
this.add(this.panel1);
this.add(this.panel2);
},
//这里直接就获取当前容器的子组件panel2并获取panel2中的formPanel进行操作
addRecordToGrid_2:function(){
var values = this.panel2.formPanel.getForm().getValues();
var record = new Ext.data.Record(values);
this.panel1.gridStore.add(record);
},
//TODO panel1的事件处理函数,在这里会获取到panel2的实例,并通过该实例获取其内部的formPanel并调用
//formPanel的相应方法来达到读取数据的目的
addRecordToForm:function(record){
this.panel2.formPanel.getForm().loadRecord(record);
}
});
Ext.onReady(function(){
var ls = new Lesson2.Main({
title:"测试",
width:400
});
});


两种写法有各自的好处.看大家怎么取舍了,当然,组件和组件之间的交互远不只这些简单的操作,还包括当一个组件还未被创建,而另外一个组件已经向这个组件发送数据等等,这些就要考虑使用一个第三方的数据组件来做中转.Extjs的StoreMgr可以做到,你也可以自己写一个符合你自己要求的数据组件,可以模仿StoreMgr写一个.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值