示例程序简述: 
这个Demo为了演示如将使用GridPanel显示数据,并为GridPanel添加工具条按钮,提供弹出式窗体新增数据。 
使用到的Ext组件 
这个Demo涉及到Ext中的GridPanel,FormPanel和Window三个组件。
效果图


现在开始讲解代码,首先看一下创建GridPanel的代码片段
复制代码 代码如下:
//定义数据列表面板类 
PersonListGridPanel = Ext.extend(Ext.grid.GridPanel, { 
insertWin: null, 
updateWin: null, 
constructor: function() { 
//添加自定义事件 
this.addEvents("rowSelect"); 
this.insertWin = new InsertPersonInfoWindow(); 
this.insertWin.on("submit", this.onInsertWinSubmit, this); 
this.updateWin = new UpdatePersonInfoWindow(); 
this.updateWin.on("submit", this.onUpdateWinSubmit, this); 
PersonListGridPanel.superclass.constructor.call(this, { 
renderTo: Ext.getBody(), 
width: 360, 
height: 300, 
frame:true, 
sm: new Ext.grid.RowSelectionModel({ 
singleSelect:true, 
listeners: { 
"rowselect": { 
fn: function(sm, rowIndex, r) { 
this.fireEvent("rowSelect", r); //触发自定义事件 
}, 
scope: this 
} 
} 
}), 
store: new Ext.data.JsonStore({ 
data: [{name: "李宗盛", age: 28, sex: "男"}, {name: "林忆莲", age: 26, sex: "女"}], 
fields: ["name", "sex", "age"] 
}), 
draggable: false, 
enableColumnMove: false, 
title: "First Grid", 
//iconCls:'icon-grid', 
colModel: new Ext.grid.ColumnModel([ 
{header: "Staff Name", width: 100, menuDisabled: true}, 
{header: "Age", width: 100, sortable: true, dataIndex: "age", align: "right", tooltip: "这里是提示信息"}, 
{header: "Sex", width: 100, sortable: true, dataIndex: "sex", align: "center"} 
]), 
tbar: [{ 
text: "添加人员", 
handler: function() { 
//*************************************************** 
//如果没有重写InsertPersonInfoWindow的Close方法 
//在调用之前需要检查其实例insertWin是否被释放 
//使用示例: 
//if (!this.insertWin) { 
// this.insertWin = new InsertPersonInfoWindow(); 
//} 
//this.insertWin.show(); 
//*************************************************** 
this.insertWin.show(); 
}, 
scope: this 
}, "-", { 
text: "修改人员", 
handler: function() { 
var r = this.getActiveRecord(); 
if (!r) return; 
//一定要先调用Show方法,而后再调用Load方法, 
//否则数据不会被呈现出来 
this.updateWin.show(); 
this.updateWin.load(r); 
}, 
scope: this 
}, "-", { 
text: "删除人员", 
handler: function() { 
var r = this.getActiveRecord(); 
if (!r) return; 
Ext.MessageBox.confirm("删除", "删除当前人员信息?", function(btn) { 
if(btn == "yes") { 
this.delRecord(r); 
} 
}, this); 
}, 
scope: this 
}] 
}); 
}, 
getActiveRecord: function() { 
var sm = this.getSelectionModel(); 
//没有选中的记录时,是抛出异常还是返回null??????? 
return (sm.getCount() === 0) ? null : sm.getSelected(); 
}, 
insert: function(r) { 
this.getStore().add(r); 
}, 
delRecord: function(r) { 
this.getStore().remove(r); 
}, 
onInsertWinSubmit: function(win, r) { 
this.insert(r); 
}, 
onUpdateWinSubmit: function(win, r) { 
alert('onUpdateWinSubmit'); 
} 
}); 
数据维护面板代码
复制代码 代码如下:
//定义数据维护面板,在后面定义的新增和修改窗体中都会使用到该面板 
PersonInfoFormPanel = Ext.extend(Ext.form.FormPanel, { 
constructor: function() { 
PersonInfoFormPanel.superclass.constructor.call(this, { 
//title: "Person Info", 
frame: true, 
width: 360, 
labelWidth: 40, 
defaultType: "textfield", 
defaults: { anchor: "92%" }, 
items: [{ 
name: "name", //注意,这里使用name属性而不是id,因为PersonInfoFormPanel会被添加和插入两个窗体使用,使用id会有冲突,导致组件不能被正确显示 
fieldLabel: "Name", 
allowBlank: false, 
emptyText: "请输入姓名", 
blankText: "姓名不能为空" 
}, { 
name: "age", 
fieldLabel: "Age", 
vtype: "age" 
}, { 
hiddenName: "sex", 
xtype: "combo", 
fieldLabel: "Sex", 
store: new Ext.data.SimpleStore({ 
fields: [ 
{name: 'Sex'} 
], 
data:[["男"], ["女"]] 
}), 
mode: 'local', 
displayField:'Sex', 
triggerAction: 'all', 
emptyText:'选择性别...' 
}] 
}) 
}, 
getValues: function() { 
if (this.getForm().isValid()) { 
return new Ext.data.Record(this.getForm().getValues()); 
} 
else { 
throw Error("Error Message"); 
} 
}, 
setValues: function(r) { 
this.getForm().loadRecord(r); 
}, 
reset: function() { 
this.getForm().reset(); 
} 
}); 
对数据的维护有新增和更新两个动作,从设计的角度来讲就需要编写两个窗体对其进行操作。细心的朋友一定会想,新增和更新的动作都是针对相同的数据表,那么能不能只写一个窗体,然后复用呢?答案是肯定的。下面我们就先写一个窗体基类。
复制代码 代码如下:
