|
Posted on 2008-04-07 11:00 oathleo 閱讀(1582) 評論(1) 編輯 收藏 所屬分類: Web
Ext是一個非常好的Ajax框架,其華麗的外觀表現(xiàn)確實令我們折服,然而一個應(yīng)用始終離開不服務(wù)器端,因此在實現(xiàn)開發(fā)中我們需要對Ext與服務(wù)器端的交互技術(shù)有較為詳細(xì)的了解,在開發(fā)中才能游刃有余地應(yīng)用。本文對Ext應(yīng)用中與服務(wù)器交互的常用方法作具體的介紹,本文的內(nèi)容大部份來源于《ExtJS實用開發(fā)指南》。 總體來說,Ext與服務(wù)器端的交互應(yīng)用可以歸結(jié)為三種類型,包含表單FormPanel的處理(提交、加載)、控件交互及用戶發(fā)起的Ajax請求等三種。 一、表單提交(submit)及加載(load) 這里說的表單是指用Ext的FormPanel建立的表單,看下面的例子:
Ext.onReady(
function
()
...
{
 ??
var
?f
=
new
?Ext.form.FormPanel(
...
{
??renderTo:
"
hello
"
,
??title:
"
用戶信息錄入框
"
,
??height:
200
,
??width:
300
,
??labelWidth:
60
,
??labelAlign:
"
right
"
,
??frame:
true
,
 ??defaults:
...
{xtype:
"
textfield
"
,width:
180
}
,
??items:[
 ??
...
{name:
"
username
"
,fieldLabel:
"
姓名
"
}
,
 ??
...
{name:
"
password
"
,fieldLabel:
"
密碼
"
,inputType:
"
password
"
}
,
 ??
...
{name:
"
email
"
,fieldLabel:
"
電子郵件
"
}
,
 ??
...
{xtype:
"
textarea
"
,name:
"
intro
"
,fieldLabel:
"
簡介
"
}
??],
 ??buttons:[
...
{text:
"
提交
"
}
,
...
{text:
"
取消
"
}
]??
?}
)
?}
);
?
要提交該表單,則可以直接調(diào)用FormPanel下面form對象的submit方法即可,代碼如下:
f.form.submit(
...
{
?????url:
"
server.js
"
,
waitTitle:
"
請稍候
"
,
?????waitMsg:
"
正在提交表單數(shù)據(jù),請稍候。。。。。。
"
?????}
);
調(diào)用submit方法后,默認(rèn)情況下服務(wù)器端應(yīng)用程序需要返回一個JSON數(shù)據(jù)對象,該對象包含兩個屬性,success的值是布爾值true或false,如果success的值為true,則表示服務(wù)器端處理成功,否則表示失??;而errors的值是一個對象,對象中的每一個屬性表示錯誤的字段名稱,而屬性值為錯誤描述。 比如,如果我們有服務(wù)器端驗證,下面的返回結(jié)果表示當(dāng)表單提交處理出錯時給客戶端返回的數(shù)據(jù)。 server.js文件中的內(nèi)容如下:
...
{
????success:?
false
,
 ????errors:?
...
{
????????username:?
"
姓名不能為空
"
,
????????times:?
"
遲到次數(shù)必須為數(shù)字!
"
????}
}
結(jié)果如圖所示:
? 當(dāng)然,如果success屬性值改為true,則表示服務(wù)器端的處理成功,此時可以在success定義的回調(diào)函數(shù)中作相應(yīng)的處理,比如下面的代碼表示在表單處理成功后,彈出提示信息,代碼如下:
?
...
{
????success:?
true
,
 ????data:?
...
{
????????username:?
"
冷雨
"
,
????????times:?
1
????}
}
下面我們看一個使用到表單數(shù)據(jù)加載的簡單示例代碼:
Ext.QuickTips.init();
 Ext.onReady(
function
()
...
{?
 ?
var
?f
=
new
?Ext.form.FormPanel(
...
{
??renderTo:
"
hello
"
,
??title:
"
用戶信息錄入框
"
,
??height:
130
,
??width:
320
,
??labelWidth:
60
,
??labelAlign:
"
right
"
,
??frame:
true
,
 ??defaults:
...
{width:
180
,xtype:
"
textfield
"
}
,
 ??items:[
...
{
???xtype:
"
textfield
"
,
???name:
"
username
"
,
???fieldLabel:
"
姓名
"
???}
,
 ???
...
{
???xtype:
"
textfield
"
,
???name:
"
times
"
,
???fieldLabel:
"
登錄次數(shù)
"
???}
??],
 ??buttons:[
...
{text:
"
加載表單數(shù)據(jù)
"
,
????handler:s}
]???
?}
);?
?
function
?s()
 ?
...
{
 ?f.form.load(
...
{
?????waitTitle:
"
請稍候
"
,
?????waitMsg:
"
正在加載表單數(shù)據(jù),請稍候。。。。。。
"
,
?????url:
"
data.js
"
,
?????success:
function
(action,form)
 ?????
...
{
??????alert(
"
加載成功!
"
);
?????}
,
?????failure:
function
(action,form)
 ?????
...
{
??????alert(
"
數(shù)據(jù)加載失?。?/span>
"
);
?????}
?????}
);?
?}
?
?}
);
?
服務(wù)器data.js中的內(nèi)容為:
...
{
????success:?
true
,
 ????data:?
...
{
????????username:?
"
冷雨
"
,
????????times:?
100
????}
}
當(dāng)點擊“加載表單數(shù)據(jù)”按鈕的時候,會執(zhí)行f這個函數(shù),f函數(shù)中直接調(diào)用f.form.load({})來加載表單中的數(shù)據(jù),load方法中的參數(shù)與submit方法類似。執(zhí)行上面的代碼,在從服務(wù)器端成功加載數(shù)據(jù)后,會自動把加載的數(shù)據(jù)設(shè)置到表單對應(yīng)的各個字段中,然后還會執(zhí)行success指定的回調(diào)函數(shù),如圖9-23所示。 ?
圖 9-23 表單數(shù)據(jù)加載示例
二、控件的交互
一些需要從服務(wù)器加載數(shù)據(jù)的控件會自動與服務(wù)器交互,比如TreePanel下面的TreeLoader、GridPanel里面用到的Store等。這些控件其實都可以加載各種類型的數(shù)據(jù),也就是理論上服務(wù)器可以返回任意數(shù)據(jù)給Ext客戶端,然后由Ext客戶端轉(zhuǎn)化成這些控件可以識別的數(shù)據(jù)。這些控件都提供了默認(rèn)的數(shù)據(jù)解析器,能解析固定格式的數(shù)據(jù)供這些控件使用,在使用這些控件的時候,我們需要仔細(xì)看這些控件的API,看他們具體能處理什么樣格式的數(shù)據(jù),這樣就可以在服務(wù)器端返回其默認(rèn)的數(shù)據(jù)格式即可。 下面,我們來看TreePanel,這是Ext中用來顯示樹結(jié)構(gòu)的控件,該控件可以通過一個url來加載樹的節(jié)點信息,并支持異步樹節(jié)點加載方式。看下面使用TreePanel的代碼:
var
?root
=
new
?Ext.tree.AsyncTreeNode(
...
{
??id:
"
root
"
,
??text:
"
樹的根
"
}
);
 ?
var
?tree
=
new
?Ext.tree.TreePanel(
...
{
??renderTo:
"
hello
"
,
??root:root,
 ??loader:?
new
?Ext.tree.TreeLoader(
...
{url:
"
treedata.js
"
}
),
??width:
100
?}
);
在代碼中,treedate.js表示服務(wù)器的程序,Ext在渲染這棵樹,需要加載樹節(jié)點的時候會向服務(wù)器發(fā)起一個請求,通過這個請求的返回結(jié)果來加載樹的節(jié)點信息。默認(rèn)情況下Ext要求服務(wù)器端返回的是一個包含樹節(jié)點信息的JSON數(shù)組,格式如下: [{節(jié)點對象1},{節(jié)點對象2}] 比如treedata.js中可以包含下面的數(shù)據(jù):
[
...
{
????????id:?
1
,
????????text:?
'
子節(jié)點1
'
,
????????leaf:?
true
????}
,
...
{
????????id:?
2
,
????????text:?
'
兒子節(jié)點2
'
,
 ????????children:?[
...
{
????????????id:?
3
,
????????????text:?
'
孫子節(jié)點
'
,
????????????leaf:?
true
????????}
]
???}
]
下面是樹的顯示結(jié)果: ?
再比如GridPanel,用于顯示表格數(shù)據(jù),GridPanel控件使用Store來存放表格中的數(shù)據(jù),而Ext中的Store通過DataReader來解析數(shù)據(jù),不同的DataReader可以解析不同的數(shù)據(jù),因此在使用表格的時候,根據(jù)客戶端使用的DataReader不同,服務(wù)器端需要返回相應(yīng)格式的數(shù)據(jù)。假如我們使用XmlReader,Store的定義如下: ?
var
?store
=
new
??Ext.data.Store(
...
{
??url:
"
hello.xml
"
,??
 ??reader:
new
?Ext.data.XmlReader(
...
{
???record:
"
row
"
}
,
???[
"
id
"
,
"
name
"
,
"
organization
"
,
"
homepage
"
])
??}
);?
使用該store的表格代碼如下:
Ext.onReady(
function
()
...
{?
 ?
var
?store
=
new
??Ext.data.Store(
...
{
??url:
"
hello.xml
"
,??
 ??reader:
new
?Ext.data.XmlReader(
...
{
???record:
"
row
"
}
,
???[
"
id
"
,
"
name
"
,
"
organization
"
,
"
homepage
"
])
??}
);?
 ?
var
?colM
=
new
?Ext.grid.ColumnModel([
...
{header:
"
項目名稱
"
,dataIndex:
"
name
"
,sortable:
true
}
,
 ?????
...
{header:
"
開發(fā)團(tuán)隊
"
,dataIndex:
"
organization
"
,sortable:
true
}
,
 ?????
...
{header:
"
網(wǎng)址
"
,dataIndex:
"
homepage
"
?}
]);
 ?
var
?grid?
=
?
new
?Ext.grid.GridPanel(
...
{
??renderTo:
"
hello
"
,
??title:
"
中國Java開源產(chǎn)品及團(tuán)隊
"
,
??height:
200
,
??width:
600
,?
??cm:colM,
??store:store,
??autoExpandColumn:
2
?}
);?
?store.load();?
?}
);
?
這里要求服務(wù)器端返回類似下面的xml數(shù)據(jù):
<?
xml?version="1.0"?encoding="UTF-8"
?>
<
dataset
>
?
<
row
>
??
<
id
>
1
</
id
>
??
<
name
>
EasyJWeb
</
name
>
??
<
organization
>
EasyJF
</
organization
>
??
<
homepage
>
www.easyjf.com
</
homepage
>
?
</
row
>
?
<
row
>
??
<
id
>
2
</
id
>
??
<
name
>
jfox
</
name
>
??
<
organization
>
huihoo
</
organization
>
??
<
homepage
>
www.huihoo.org
</
homepage
>
?
</
row
>
?
<
row
>
??
<
id
>
3
</
id
>
??
<
name
>
jdon
</
name
>
??
<
organization
>
jdon
</
organization
>
??
<
homepage
>
www.jdon.com
</
homepage
>
?
</
row
>
?
<
row
>
??
<
id
>
4
</
id
>
??
<
name
>
springside
</
name
>
??
<
organization
>
springside
</
organization
>
??
<
homepage
>
www.springside.org.cn
</
homepage
>
?
</
row
>
</
dataset
>
三、?Ext.Ajax.request方法
其實,不管是FormPanel的處理,還是控件的交互,他們在訪問服務(wù)器端的時候,90%都是通過使用Ext.Ajax.request方法來進(jìn)行的,該方法可以用來向服務(wù)器端發(fā)送一個http請求,并可以在回調(diào)函數(shù)中處理返回的結(jié)果。往遠(yuǎn)程服務(wù)器發(fā)送一個HTTP請求,發(fā)送Ajax調(diào)用的時候該方法的簽名如下: Ext.Ajax.rquest( [Object options] ) : Number
服務(wù)器的響應(yīng)是異步的,因此需要在回調(diào)函數(shù)中處理服務(wù)器端返回的數(shù)據(jù)。回調(diào)函數(shù)可以定義在request方法調(diào)用的參數(shù)options中。另外,在request方法中可以定義Ajax請求的一些其它屬性。參數(shù)options是一個對象,該對象包含了Ajax請求所需的各種參數(shù)及回調(diào)處理參數(shù)等。options中可以包含的各個屬性及含義如下所示: url?String?指定要請求的服務(wù)器端url,默認(rèn)值為Ajax對象中配置的URL參數(shù)值。 params?Object/String/Function?指定要傳遞的參數(shù),可以是一個包含參數(shù)名稱及值的對象,也可以是name=xx&birthday=1978-1-1類似的url編碼字符串,或者是一個能返回上述兩種內(nèi)容的函數(shù)。 method?String?指定發(fā)送Ajax請求使用的method,可以是GET或POST方式。默認(rèn)情況下,如果請求中沒有傳遞任何參數(shù)則使用GET,否則使用POST。 callback?Function?指定Ajax請求的回調(diào)函數(shù),該函數(shù)不管是調(diào)用成功或失敗,都會執(zhí)行。傳遞給回調(diào)函數(shù)的參數(shù)有三個,第一個options表示執(zhí)行request方法時的參數(shù),第二個success表示請求是否成功,第三個參數(shù)response表示用來執(zhí)行Ajax請求的XMLHttpRequest 對象。關(guān)于XMLHttpRequest可以通過http://www.w3.org/TR/XMLHttpRequest/查詢詳細(xì)的信息。 success?Function?指定當(dāng)Ajax請求執(zhí)行成功后執(zhí)行的回調(diào)函數(shù),傳遞給回調(diào)函數(shù)兩個參數(shù),第一個參數(shù)response表示執(zhí)行Ajax請求的XMLHttpRequet對象,第二個參數(shù)表示執(zhí)行request方法時的options對象。 failure?Function?指定當(dāng)請求出現(xiàn)錯誤時執(zhí)行的回調(diào)函數(shù),傳遞給回調(diào)函數(shù)兩個參數(shù),第一個參數(shù)response表示執(zhí)行Ajax請求的XMLHttpRequet對象,第二個參數(shù)表示執(zhí)行request方法時的options對象。 scope?Object?指定回調(diào)函數(shù)的作用域,默認(rèn)為瀏覽器window。 form?Object/String?指定要提交的表單id或表單數(shù)據(jù)對象。 isUpload?Boolean?指定要提交的表單是否是文件上傳表單,默認(rèn)情況下會自動檢查。 headers?Object?指定請求的Header信息。 xmlData?Object?指定用于發(fā)送給服務(wù)器的xml文檔,如果指定了該屬性則其它地方設(shè)置的參數(shù)將無效。 jsonData?Object/String?指定需要發(fā)送給服務(wù)器端的JSON數(shù)據(jù)。如果指定了該屬性則其它的地方設(shè)置的要發(fā)送的參數(shù)值將無效。 disableCaching?Boolean?是否禁止cache。
比如,下面是一個向服務(wù)器foo.ejf這個應(yīng)用程序發(fā)起一個Ajax請求的應(yīng)用示例程序:
function
?successFn(response,options)
...
{
alert(
'
請求成功了
'
);
}
function
?failureFn(response,options)
...
{
alert(
'
請求失敗了
'
);
}
Ext.Ajax.request(
...
{
???url:?
'
foo.ejf
'
,
???success:?successFn,
???failure:?failureFn,??
 ???params:?
...
{?foo:?
'
bar
'
?}
}
);

這里的回調(diào)函數(shù)返回中返回的參數(shù)是一個XHR(即XmlHttpRequest)對象,我們可以通過該對象的responseText或responseXML等屬性來得到從服務(wù)器端返回的數(shù)據(jù)信息。在Ajax應(yīng)用中,我們經(jīng)常會讓服務(wù)器端返回JSON數(shù)據(jù),由于JSON數(shù)據(jù)是字符串,因此在程序中需要先把他解析成javascript對象才可以使用,把JSON數(shù)據(jù)解析成javascript對象可以直接使用Ext.decode方法。 假如服務(wù)器返回的是下面的JSON數(shù)據(jù)對象: { ??????? username: "冷雨", ??????? times: 1 } ?則回調(diào)函數(shù)中應(yīng)用這樣來使用該對象:
function
?successFn(response,options)
...
{
var
?obj
=
?Ext.decode(response.responseText)?;
alert(obj.username);
}
??? Ext.Ajax.request是Ext與服務(wù)器端交互的核心,因此需要在應(yīng)用中靈活使用。在下一篇文章中,我會對Ext應(yīng)用中的服務(wù)器程序作介紹。本文的文字、代碼及圖片等均來源于《ExtJS實用開發(fā)指南》,版權(quán)歸原作者所有,該指南當(dāng)前在北京、深圳、成都、重慶、沈陽、杭州、上海等城市均已經(jīng)可以直接到服務(wù)點購買,具體聯(lián)系方式:http://www.vifir.com/stations.html。)。
Feedback
# re: Ext服務(wù)器交互技術(shù)詳解(一) 回復(fù) 更多評論
2008-04-22 10:00 by
頂~~~ 就需要這樣的資料
|