ExtJS中FormPanel實現數據加載和提交 - EXT - AJAX - JavaEye論壇

導讀:


在使用使用FormPanel時我們通常需要使用它的form對象來加載數據或提交數據。FormPanel中的 form對象爲Ext.form.BasicForm類型的對象,它有load和submit方法分別用於加載數據和提交數據。而這兩個方法都是通過調用 Ext.form.BasicForm中的doAction方法來操作的。doAction方法帶有兩個參數,其中第二個參數爲從load或submit 方法傳遞過來的Ext.form.Action對象的配置數據(Config Options)。其中的success和failure屬性是用於處理請求成功或失敗的函數。但需要注意的是,文檔中的說明是這個success或 failure取決於Http請求過程是否出錯。實際情況卻並非這樣,我在開發過程中發現HTTP響應代碼一直都是200,但被調用的函數卻一直都是 failure屬性對應的函數。通過查看Action.js可以發現響應過來的數據是需要符合一定格式的,Ext.form.Action.Load的 API文檔開頭就說明了響應數據包必須類似下面的格式:

{

: true,
data: {
clientName: "Fred. Olsen Lines",
portOfLoading: "FXT",
portOfDischarge: "OSL"
}
}
這個說明在我使用ExtJS的時候再次誤導了我。我認爲只需要響應的數據爲類似的格式就可以了。結果仍然出錯,查看Action.js中的 handleResponse方法可以看出,返回的數據爲上面代碼的格式,但並不是說從服務端發送過來的數據就是這樣的格式,而是需要將 Ext.form.Action.Load的result屬性設置成上面的格式的數據。從handleResponse也可以看出,Action.js使用了form.reader屬性來處理服務端數據。這個屬性也可以在初始化FormPanel的時候傳遞給FormPanel,FormPanel將會把這個屬性傳遞給它內置的BasicForm對象。怎樣使用JsonReader來使提取響應數據來使它滿足PanelForm的要求呢?再看 handleResponse中的代碼,在reader存在的情況下,它返回的是所需要的格式的數據,一個包含success屬性和data屬性的對象,而data屬性來自於JsonReader的read方法處理後的結果。再查看JsonReader.js中的read方法,它調用的是 readRecords來讀取數據,而返回的值是由reader的root屬性決定的,從JsonReader.js中還可以看出,root屬性對應的 JSON對象必須是集合類型的,因此我們在後臺發送過來的數據必須也是集合類型,我在這裏也出了錯。一直認爲加載數據到Form裏,一次只加載一條,所以從服務端傳遞過來的數據都是單個的對象,而將JsonReader對象的root設置爲單個對象的名稱,結果Form中一直都加載不上數據。後來將服務端傳遞過來的數據修改爲集合數型問題解決了。

小結:



  1. ExtJS中JsonReader對於數據的處理總是一致的,不管你需要的是單條記錄還是多條記錄,它總是通過total屬性判斷記錄數,通過root屬性對應的名稱來取記錄集合。
  2. FormPanel中處理數據的爲內置的BasicForm類型的對象,它通過load和submit方法來加載或提交數據。而這兩個方法是通過 Ext.form.Action的兩個子類Ext.form.Action.Load、Ext.form.Action.Submit來提交請求和調用用戶的success和failure方法。決定調用success和failure的並非Http請求是否出錯,而是決定於Action.js中 handleResponse的處理結果。我們可以通過設置FormPanel的reader配置對象來干預handleResponse對數據的處理。而這個reader也可設置響應數據與FormPanel中字段的對應關係。
  3. 多看源碼,可以獲取更多。

附:


表格中雙擊進行編輯的JS源碼,這個代碼比官方文檔中的處理方式簡單一些,覺得官方文檔中的edit中加載數據的處理是一種hack的方式,並不太適合實際應用。


ExtJS網站上的CRUD的文章,其中包含有加載數據進行編輯的例子

.onReady(function(){

var newFormWin;
var form1;

//表格處理
//.BLANK_IMAGE_URL = 'js/resources/images/default/s.gif';
.QuickTips.init();
var sm = new .grid.CheckboxSelectionModel(); //CheckBox選擇列

var cm = new .grid.ColumnModel([
new .grid.RowNumberer(), //行號列
sm,
{header:'編號',dataIndex:'id'},
{header:'性別',dataIndex:'sex',renderer:function(value){
if(value=='1'){
return "男";
}else{
return "女";
}
}}, //增加性別,自定義renderer,即顯示的樣式,可以加html代碼,來顯示圖片等。
{header:'名稱',dataIndex:'name'},
{header:'描述',dataIndex:'memo'}
]);

var ds = new .data.Store({
proxy: new .data.HttpProxy({url:_URL}),//調用的動作
reader: new .data.JsonReader({
totalProperty: 'total',
root: 'list',
Property :''
},
[{name: 'id',mapping:'id',type:'string'},
{name: 'sex',mapping:'sex',type:'string'},
{name: 'name',mapping:'name',type:'string'},
{name: 'memo',mapping:'memo',type:'string'} //列的映射
])
});


var grid = new .grid.GridPanel({
id: 'grid',
el: 'center',
region:'center',
title:'用戶',
ds: ds,
sm: sm,
cm: cm,
bbar: new .PagingToolbar({
pageSize: 10,
store: ds,
displayInfo: true,
displayMsg: '顯示第 {0} 條到 {1} 條記錄,一共 {2} 條',
emptyMsg: "沒有記錄"
}) //頁腳顯示分頁
});


//佈局處理
.state.Manager.setProvider(new .state.CookieProvider());
new .Viewport({
layout:'border',
items:[
{
xtype:'box',
region:'north',
el: 'north',
height:32,
title:'north'
},{
region:'south',
contentEl: 'south',
split:true,
height: 100,
minSize: 100,
maxSize: 200,
collapsible: true,
title:'South',
margins:'0 0 0 0'
},
grid
]
});

//el:指定html元素用於顯示grid
grid.render();//.getCmp('grid').render();//渲染表格
ds.load({params:{start:0, limit:10}}); //加載數據

grid.on("rowdblclick", function(grid) {
loadFormData(grid);
//alert(form1.reader);
});

// 載入被選擇的數據行的表單數據
var loadFormData = function(grid) {
var _record = grid.getSelectionModel().getSelected();
if (!_record) {
.example.msg('修改操作', '請選擇要修改的一項!');
} else {
myFormWin();
form1.form.load( {
url : EDIT__URL+'?sid='+ _record.get('id'),
waitMsg : '正在載入數據...',
: function(form,) {
.example.msg('編輯', '載入成功!');
},
failure : function(form,) {
.example.msg('編輯', '載入失敗');
}
});
}
};




var myFormWin = function() {
// create the window on the first click and reuse on subsequent
// clicks

if (!newFormWin) {
newFormWin = new .Window( {
el : 'topic-win',
layout : 'fit',
width : 400,
height : 300,
close : 'hide',
plain : true,
title : '窗口',
items : form1
});
}
newFormWin.show('New1');
};



form1 = new .FormPanel( {
// collapsible : true,// 是否可以展開
labelWidth : 75, // label settings here cascade unless overridden
url : 'AddLevel.',
frame : true,
title : '修改',
bodyStyle : 'padding:5px 5px 0',
width : 350,
waitMsgTarget : true,
//這個屬性決定了load和submit中對數據的處理,list必須是一個集合類型,json格式應該是[]包含的一個數組
reader: new .data.JsonReader({root:'list'},
[{name: 'id',mapping:'id',type:'string'},
{name: 'sex',mapping:'sex',type:'string'},
{name: 'memo',mapping:'memo',type:'string'}
]),
defaults : {
width : 230
},
defaultType : 'tfield',
items : [ {
fieldLabel : '編號',
name : 'id',
allowBlank : false
}, {
fieldLabel : '性別',
name : 'sex',
allowBlank : false
}, new .form.TArea( {
fieldLabel : '備註',
name : 'memo',
growMin : 234
})],

buttons : [ {
t : '保存',
disabled : false,
handler : function() {
if (form1.form.isValid()) {
form1.form.submit( {
url : 'AddLevel.',
: function(from, ) {
.example.msg('保存成功', '添加級別成功!');
ds.load( {
params : {
start : 0,
limit : 30,
forumId : 4
}
});
},
failure : function(form, ) {
.example.msg('保存失敗', '添加級別失敗!');
},
waitMsg : '正在保存數據,稍後...'
});
dialog.hide();
} else {
.Msg.alert('信息', '請填寫完成再提交!');
}
}
}, {
t : '取消',
handler : function() {
newFormWin.hide();
}
}]
});



});


本文轉自
http://www.javaeye.com/topic/173897
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章