您的位置:首页 > 其它

Ext面向对象开发实践(turn)

2009-08-19 14:00 501 查看
示例程序简述:

这个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();

}

});

对数据的维护有新增和更新两个动作,从设计的角度来讲就需要编写两个窗体对其进行操作。细心的朋友一定会想,新增和更新的动作都是针对相同的数据表,那么能不能只写一个窗体,然后复用呢?答案是肯定的。下面我们就先写一个窗体基类。

//新增,修改窗体基类

PersonInfoWindow = Ext.extend(Ext.Window, {

form: null,

constructor: function() {

this.addEvents("submit");

this.form = new PersonInfoFormPanel();

//Ext.apply(this.form, {baseCls: "x-plain"});

PersonInfoWindow.superclass.constructor.call(this, {

plain: true,

width: 360,

modal: true, //模式窗体

onEsc: Ext.emptyFn,

closeAction: "hide",

items: [this.form],

buttons: [{

text: "确 定",

handler: this.onSubmitClick,

scope: this

}, {

text: "取 消",

handler: this.onCancelClick,

scope: this

}]

});

//alert(this.onSubmitClick);

},

close: function() {

//需要重写CLose方法,

//否则在窗体被关闭其实体会被释放

this.hide();

this.form.reset();

},

onSubmitClick: function() {

//alert(Ext.util.JSON.encode(this.form.getValues().data));

try {

this.fireEvent("submit", this, this.form.getValues());

this.close();

}

catch(_err) {

return;

}

},

onCancelClick: function() {

this.close();

}

});

基类写了之后,我们就可以使用继承的方法来编写新进和更新窗体了。

//定义新增数据窗体

InsertPersonInfoWindow = Ext.extend(PersonInfoWindow, {

title: "添加"

});

//==============================================================================

//定义编辑数据窗体

UpdatePersonInfoWindow = Ext.extend(PersonInfoWindow, {

title: "修改",

load: function(r) {

this.form.setValues(r);

}

});

为了区分新增和更新窗体,我们在其各自的实现类中为其指定了Title属性,另外在更新窗体类中需要另外添加一个用于加载待编辑数据的方法Load。

脚本部分算是完成了,下面看看如何在HTML中使用。HTML中的引用代码

<script type="text/javascript">

Ext.QuickTips.init();

Ext.form.Field.prototype.msgTarget = "side";

Ext.BLANK_IMAGE_URL = "http://localhost:8080/ext-2.2/resources/images/default/s.gif";

Ext.apply(Ext.form.VTypes, {

"age": function(_v) {

if (/^\d+$/.test(_v)) {

var _age = parseInt(_v);

if ((_age > 0) && (_age < 200)) return true;

}

return false;

},

"ageText": "年龄必须在0到200之间",

"ageMask": /[0-9]/i

});

Ext.onReady(function() {

new PersonListGridPanel();

});

</script>

代码很简洁,也很清晰。只需要创建一个PersonListGridPanel即可,因为它自身包含了新增、修改的窗体对象,而新增和修改窗体中都使用到了负责数据编辑的PersonInfoFormPanel。

在PersonInfoFormPanel中使用了VTypes进行数据验证。

新增和修改窗体仅仅是界面,负责将用户在PersonInfoFormPanel中填写的数据传回到ListGrid中以便保存,或是将ListGrid中的数据传递到PersonInfoFormPanel中进行呈现,供用户编辑。

附上完整的HTML代码和JavaScript代码文件。

Grid.html

<html>

<head>

<title>Ext Grid</title>

<link rel="stylesheet" type="text/css" href="http://localhost:8080/ext-2.2/resources/css/ext-all.css"/>

<script type="text/javascript" src="http://localhost:8080/ext-2.2/adapter/ext/ext-base.js"></script>

<script type="text/javascript" src="http://localhost:8080/ext-2.2/ext-all.js"></script>

<script type="text/javascript" src="PersonListGridPanel.js"></script>

<script type="text/javascript">

Ext.QuickTips.init();

Ext.form.Field.prototype.msgTarget = "side";

Ext.BLANK_IMAGE_URL = "http://localhost:8080/ext-2.2/resources/images/default/s.gif";

Ext.apply(Ext.form.VTypes, {

"age": function(_v) {

if (/^\d+$/.test(_v)) {

var _age = parseInt(_v);

if ((_age > 0) && (_age < 200)) return true;

}

return false;

},

"ageText": "年龄必须在0到200之间",

"ageMask": /[0-9]/i

});

Ext.onReady(function() {

new PersonListGridPanel();

});

</script>

</head>

<body>

</body>

</html>

PersonListGridPanel.js

//定义数据列表面板类

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: [{

name: "btnFirst",

//text: "First",

iconCls: "x-tbar-page-first",

handler: function () {

this.getSelectionModel().selectFirstRow();

},

scope: this

}, {

name: "btnPrev",

//text: "Prev",

iconCls: "x-tbar-page-prev",

handler: function () {

this.getSelectionModel().selectPrevious();

},

scope: this

}, {

name: "btnNext",

//text: "Next",

iconCls: "x-tbar-page-next",

handler: function () {

this.getSelectionModel().selectNext();

},

scope: this

}, {

name: "btnLast",

//text: "Last",

iconCls: "x-tbar-page-last",

handler: function () {

this.getSelectionModel().selectLastRow();

},

scope: this

}, "-", {

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;

//如何将数据填充到窗体中?

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("信息不完整");

}

},

setValues: function(r) {

//alert(Ext.util.JSON.encode(r.data));

this.getForm().loadRecord(r);

},

reset: function() {

this.getForm().reset();

}

});

//==============================================================================

//新增,修改窗体基类

PersonInfoWindow = Ext.extend(Ext.Window, {

form: null,

constructor: function() {

this.addEvents("submit");

this.form = new PersonInfoFormPanel();

//Ext.apply(this.form, {baseCls: "x-plain"});

PersonInfoWindow.superclass.constructor.call(this, {

plain: true,

width: 360,

modal: true, //模式窗体

onEsc: Ext.emptyFn,

closeAction: "hide",

items: [this.form],

buttons: [{

text: "确 定",

handler: this.onSubmitClick,

scope: this

}, {

text: "取 消",

handler: this.onCancelClick,

scope: this

}]

});

//alert(this.onSubmitClick);

},

close: function() {

//需要重写CLose方法,

//否则在窗体被关闭其实体会被释放

this.hide();

this.form.reset();

},

onSubmitClick: function() {

//alert(Ext.util.JSON.encode(this.form.getValues().data));

try {

this.fireEvent("submit", this, this.form.getValues());

this.close();

}

catch(_err) {

return;

}

},

onCancelClick: function() {

this.close();

}

});

//==============================================================================

//定义新增数据窗体

InsertPersonInfoWindow = Ext.extend(PersonInfoWindow, {

title: "添加"

});

//==============================================================================

//定义编辑数据窗体

UpdatePersonInfoWindow = Ext.extend(PersonInfoWindow, {

title: "修改",

load: function(r) {

this.form.setValues(r);

}

});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: