Ext是一個(gè)非常好的Ajax框架,其華麗的外觀表現(xiàn)確實(shí)令我們折服,然而一個(gè)應(yīng)用始終離開(kāi)不服務(wù)器端,因此在實(shí)現(xiàn)開(kāi)發(fā)中我們需要對(duì)Ext與服務(wù)器端的交互技術(shù)有較為詳細(xì)的了解,在開(kāi)發(fā)中才能游刃有余地應(yīng)用。本文對(duì)Ext應(yīng)用中與服務(wù)器交互的常用方法作具體的介紹,本文的內(nèi)容大部份來(lái)源于《ExtJS實(shí)用開(kāi)發(fā)指南》。
總體來(lái)說(shuō),Ext與服務(wù)器端的交互應(yīng)用可以歸結(jié)為三種類型,包含表單FormPanel的處理(提交、加載)、控件交互及用戶發(fā)起的Ajax請(qǐng)求等三種。
一、表單提交(submit)及加載(load)
這里說(shuō)的表單是指用Ext的FormPanel建立的表單,看下面的例子:




















要提交該表單,則可以直接調(diào)用FormPanel下面form對(duì)象的submit方法即可,代碼如下:





調(diào)用submit方法后,默認(rèn)情況下服務(wù)器端應(yīng)用程序需要返回一個(gè)JSON數(shù)據(jù)對(duì)象,該對(duì)象包含兩個(gè)屬性,success的值是布爾值true或false,如果success的值為true,則表示服務(wù)器端處理成功,否則表示失敗;而errors的值是一個(gè)對(duì)象,對(duì)象中的每一個(gè)屬性表示錯(cuò)誤的字段名稱,而屬性值為錯(cuò)誤描述。
比如,如果我們有服務(wù)器端驗(yàn)證,下面的返回結(jié)果表示當(dāng)表單提交處理出錯(cuò)時(shí)給客戶端返回的數(shù)據(jù)。
server.js文件中的內(nèi)容如下:







結(jié)果如圖所示:
當(dāng)然,如果success屬性值改為true,則表示服務(wù)器端的處理成功,此時(shí)可以在success定義的回調(diào)函數(shù)中作相應(yīng)的處理,比如下面的代碼表示在表單處理成功后,彈出提示信息,代碼如下:









另外一種表單動(dòng)作是表單中數(shù)據(jù)的加載。要給表單中的字段設(shè)置值,可以通過(guò)調(diào)用字段的setValue方法,也可以直接在初始化字段的時(shí)候在配置參數(shù)中設(shè)置value屬性值,另外還有一種方法是通過(guò)Ajax的方式從服務(wù)器端加載表單中各個(gè)字段的值。這種方式也就是我們這里要介紹的表單數(shù)據(jù)加載。
ExtJS的表單數(shù)據(jù)加載通過(guò)BasicForm的load方法來(lái)進(jìn)行,表單數(shù)據(jù)加載動(dòng)作由類Ext.form.Action.Load定義,執(zhí)行數(shù)據(jù)加載動(dòng)作會(huì)到服務(wù)器端加載數(shù)據(jù),默認(rèn)情況下服務(wù)器端需要返回一個(gè)包含success屬性及data屬性的JSON對(duì)象,內(nèi)容大致如下:







下面我們看一個(gè)使用到表單數(shù)據(jù)加載的簡(jiǎn)單示例代碼:












































服務(wù)器data.js中的內(nèi)容為:







當(dāng)點(diǎn)擊“加載表單數(shù)據(jù)”按鈕的時(shí)候,會(huì)執(zhí)行f這個(gè)函數(shù),f函數(shù)中直接調(diào)用f.form.load({})來(lái)加載表單中的數(shù)據(jù),load方法中的參數(shù)與submit方法類似。執(zhí)行上面的代碼,在從服務(wù)器端成功加載數(shù)據(jù)后,會(huì)自動(dòng)把加載的數(shù)據(jù)設(shè)置到表單對(duì)應(yīng)的各個(gè)字段中,然后還會(huì)執(zhí)行success指定的回調(diào)函數(shù),如圖9-23所示。
圖 9-23 表單數(shù)據(jù)加載示例
二、控件的交互
一些需要從服務(wù)器加載數(shù)據(jù)的控件會(huì)自動(dòng)與服務(wù)器交互,比如TreePanel下面的TreeLoader、GridPanel里面用到的Store等。這些控件其實(shí)都可以加載各種類型的數(shù)據(jù),也就是理論上服務(wù)器可以返回任意數(shù)據(jù)給Ext客戶端,然后由Ext客戶端轉(zhuǎn)化成這些控件可以識(shí)別的數(shù)據(jù)。這些控件都提供了默認(rèn)的數(shù)據(jù)解析器,能解析固定格式的數(shù)據(jù)供這些控件使用,在使用這些控件的時(shí)候,我們需要仔細(xì)看這些控件的API,看他們具體能處理什么樣格式的數(shù)據(jù),這樣就可以在服務(wù)器端返回其默認(rèn)的數(shù)據(jù)格式即可。
下面,我們來(lái)看TreePanel,這是Ext中用來(lái)顯示樹(shù)結(jié)構(gòu)的控件,該控件可以通過(guò)一個(gè)url來(lái)加載樹(shù)的節(jié)點(diǎn)信息,并支持異步樹(shù)節(jié)點(diǎn)加載方式。看下面使用TreePanel的代碼:









在代碼中,treedate.js表示服務(wù)器的程序,Ext在渲染這棵樹(shù),需要加載樹(shù)節(jié)點(diǎn)的時(shí)候會(huì)向服務(wù)器發(fā)起一個(gè)請(qǐng)求,通過(guò)這個(gè)請(qǐng)求的返回結(jié)果來(lái)加載樹(shù)的節(jié)點(diǎn)信息。默認(rèn)情況下Ext要求服務(wù)器端返回的是一個(gè)包含樹(shù)節(jié)點(diǎn)信息的JSON數(shù)組,格式如下:
[{節(jié)點(diǎn)對(duì)象1},{節(jié)點(diǎn)對(duì)象2}]
比如treedata.js中可以包含下面的數(shù)據(jù):














下面是樹(shù)的顯示結(jié)果:
再比如GridPanel,用于顯示表格數(shù)據(jù),GridPanel控件使用Store來(lái)存放表格中的數(shù)據(jù),而Ext中的Store通過(guò)DataReader來(lái)解析數(shù)據(jù),不同的DataReader可以解析不同的數(shù)據(jù),因此在使用表格的時(shí)候,根據(jù)客戶端使用的DataReader不同,服務(wù)器端需要返回相應(yīng)格式的數(shù)據(jù)。假如我們使用XmlReader,Store的定義如下:







使用該store的表格代碼如下:






















這里要求服務(wù)器端返回類似下面的xml數(shù)據(jù):




























三、 Ext.Ajax.request方法
其實(shí),不管是FormPanel的處理,還是控件的交互,他們?cè)谠L問(wèn)服務(wù)器端的時(shí)候,90%都是通過(guò)使用Ext.Ajax.request方法來(lái)進(jìn)行的,該方法可以用來(lái)向服務(wù)器端發(fā)送一個(gè)http請(qǐng)求,并可以在回調(diào)函數(shù)中處理返回的結(jié)果。往遠(yuǎn)程服務(wù)器發(fā)送一個(gè)HTTP請(qǐng)求,發(fā)送Ajax調(diào)用的時(shí)候該方法的簽名如下:
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請(qǐng)求的一些其它屬性。參數(shù)options是一個(gè)對(duì)象,該對(duì)象包含了Ajax請(qǐng)求所需的各種參數(shù)及回調(diào)處理參數(shù)等。options中可以包含的各個(gè)屬性及含義如下所示:
url String 指定要請(qǐng)求的服務(wù)器端url,默認(rèn)值為Ajax對(duì)象中配置的URL參數(shù)值。
params Object/String/Function 指定要傳遞的參數(shù),可以是一個(gè)包含參數(shù)名稱及值的對(duì)象,也可以是name=xx&birthday=1978-1-1類似的url編碼字符串,或者是一個(gè)能返回上述兩種內(nèi)容的函數(shù)。
method String 指定發(fā)送Ajax請(qǐng)求使用的method,可以是GET或POST方式。默認(rèn)情況下,如果請(qǐng)求中沒(méi)有傳遞任何參數(shù)則使用GET,否則使用POST。
callback Function 指定Ajax請(qǐng)求的回調(diào)函數(shù),該函數(shù)不管是調(diào)用成功或失敗,都會(huì)執(zhí)行。傳遞給回調(diào)函數(shù)的參數(shù)有三個(gè),第一個(gè)options表示執(zhí)行request方法時(shí)的參數(shù),第二個(gè)success表示請(qǐng)求是否成功,第三個(gè)參數(shù)response表示用來(lái)執(zhí)行Ajax請(qǐng)求的XMLHttpRequest 對(duì)象。關(guān)于XMLHttpRequest可以通過(guò)http://www.w3.org/TR/XMLHttpRequest/查詢?cè)敿?xì)的信息。
success Function 指定當(dāng)Ajax請(qǐng)求執(zhí)行成功后執(zhí)行的回調(diào)函數(shù),傳遞給回調(diào)函數(shù)兩個(gè)參數(shù),第一個(gè)參數(shù)response表示執(zhí)行Ajax請(qǐng)求的XMLHttpRequet對(duì)象,第二個(gè)參數(shù)表示執(zhí)行request方法時(shí)的options對(duì)象。
failure Function 指定當(dāng)請(qǐng)求出現(xiàn)錯(cuò)誤時(shí)執(zhí)行的回調(diào)函數(shù),傳遞給回調(diào)函數(shù)兩個(gè)參數(shù),第一個(gè)參數(shù)response表示執(zhí)行Ajax請(qǐng)求的XMLHttpRequet對(duì)象,第二個(gè)參數(shù)表示執(zhí)行request方法時(shí)的options對(duì)象。
scope Object 指定回調(diào)函數(shù)的作用域,默認(rèn)為瀏覽器window。
form Object/String 指定要提交的表單id或表單數(shù)據(jù)對(duì)象。
isUpload Boolean 指定要提交的表單是否是文件上傳表單,默認(rèn)情況下會(huì)自動(dòng)檢查。
headers Object 指定請(qǐng)求的Header信息。
xmlData Object 指定用于發(fā)送給服務(wù)器的xml文檔,如果指定了該屬性則其它地方設(shè)置的參數(shù)將無(wú)效。
jsonData Object/String 指定需要發(fā)送給服務(wù)器端的JSON數(shù)據(jù)。如果指定了該屬性則其它的地方設(shè)置的要發(fā)送的參數(shù)值將無(wú)效。
disableCaching Boolean 是否禁止cache。
比如,下面是一個(gè)向服務(wù)器foo.ejf這個(gè)應(yīng)用程序發(fā)起一個(gè)Ajax請(qǐng)求的應(yīng)用示例程序:















這里的回調(diào)函數(shù)返回中返回的參數(shù)是一個(gè)XHR(即XmlHttpRequest)對(duì)象,我們可以通過(guò)該對(duì)象的responseText或responseXML等屬性來(lái)得到從服務(wù)器端返回的數(shù)據(jù)信息。在Ajax應(yīng)用中,我們經(jīng)常會(huì)讓服務(wù)器端返回JSON數(shù)據(jù),由于JSON數(shù)據(jù)是字符串,因此在程序中需要先把他解析成javascript對(duì)象才可以使用,把JSON數(shù)據(jù)解析成javascript對(duì)象可以直接使用Ext.decode方法。
假如服務(wù)器返回的是下面的JSON數(shù)據(jù)對(duì)象:
{
username: "冷雨",
times: 1
}
則回調(diào)函數(shù)中應(yīng)用這樣來(lái)使用該對(duì)象:




Ext.Ajax.request是Ext與服務(wù)器端交互的核心,因此需要在應(yīng)用中靈活使用。在下一篇文章中,我會(huì)對(duì)Ext應(yīng)用中的服務(wù)器程序作介紹。本文的文字、代碼及圖片等均來(lái)源于《ExtJS實(shí)用開(kāi)發(fā)指南》,版權(quán)歸原作者所有,該指南當(dāng)前在北京、深圳、成都、重慶、沈陽(yáng)、杭州、上海等城市均已經(jīng)可以直接到服務(wù)點(diǎn)購(gòu)買,具體聯(lián)系方式:http://www.vifir.com/stations.html。)。