Ext是一個非常好的Ajax框架,其華麗的外觀表現確實令我們折服,然而一個應用始終離開不服務器端,因此在實現開發中我們需要對Ext與服務器端的交互技術有較為詳細的了解,在開發中才能游刃有余地應用。本文對Ext應用中與服務器交互的常用方法作具體的介紹,本文的內容大部份來源于《ExtJS實用開發指南》。
總體來說,Ext與服務器端的交互應用可以歸結為三種類型,包含表單FormPanel的處理(提交、加載)、控件交互及用戶發起的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:"取消"}]
})
});


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

f.form.submit(...{
url:"server.js",
waitTitle:"請稍候",
waitMsg:"正在提交表單數據,請稍候。。。。。。"
});
調用submit方法后,默認情況下服務器端應用程序需要返回一個JSON數據對象,該對象包含兩個屬性,success的值是布爾值true或false,如果success的值為true,則表示服務器端處理成功,否則表示失敗;而errors的值是一個對象,對象中的每一個屬性表示錯誤的字段名稱,而屬性值為錯誤描述。
比如,如果我們有服務器端驗證,下面的返回結果表示當表單提交處理出錯時給客戶端返回的數據。
server.js文件中的內容如下:

...{
success: false,

errors: ...{
username: "姓名不能為空",
times: "遲到次數必須為數字!"
}
}
結果如圖所示:

當然,如果success屬性值改為true,則表示服務器端的處理成功,此時可以在success定義的回調函數中作相應的處理,比如下面的代碼表示在表單處理成功后,彈出提示信息,代碼如下:

...{
success: true,

data: ...{
username: "冷雨",
times: 1
}
}
下面我們看一個使用到表單數據加載的簡單示例代碼:
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:"登錄次數"
}
],

buttons:[...{text:"加載表單數據",
handler:s}]
});
function s()

...{

f.form.load(...{
waitTitle:"請稍候",
waitMsg:"正在加載表單數據,請稍候。。。。。。",
url:"data.js",
success:function(action,form)

...{
alert("加載成功!");
},
failure:function(action,form)

...{
alert("數據加載失敗!");
}
});
}
});

服務器data.js中的內容為:

...{
success: true,

data: ...{
username: "冷雨",
times: 100
}
}
當點擊“加載表單數據”按鈕的時候,會執行f這個函數,f函數中直接調用f.form.load({})來加載表單中的數據,load方法中的參數與submit方法類似。執行上面的代碼,在從服務器端成功加載數據后,會自動把加載的數據設置到表單對應的各個字段中,然后還會執行success指定的回調函數,如圖9-23所示。

圖 9-23 表單數據加載示例
二、控件的交互
一些需要從服務器加載數據的控件會自動與服務器交互,比如TreePanel下面的TreeLoader、GridPanel里面用到的Store等。這些控件其實都可以加載各種類型的數據,也就是理論上服務器可以返回任意數據給Ext客戶端,然后由Ext客戶端轉化成這些控件可以識別的數據。這些控件都提供了默認的數據解析器,能解析固定格式的數據供這些控件使用,在使用這些控件的時候,我們需要仔細看這些控件的API,看他們具體能處理什么樣格式的數據,這樣就可以在服務器端返回其默認的數據格式即可。
下面,我們來看TreePanel,這是Ext中用來顯示樹結構的控件,該控件可以通過一個url來加載樹的節點信息,并支持異步樹節點加載方式。看下面使用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表示服務器的程序,Ext在渲染這棵樹,需要加載樹節點的時候會向服務器發起一個請求,通過這個請求的返回結果來加載樹的節點信息。默認情況下Ext要求服務器端返回的是一個包含樹節點信息的JSON數組,格式如下:
[{節點對象1},{節點對象2}]
比如treedata.js中可以包含下面的數據:

[...{
id: 1,
text: '子節點1',
leaf: true

},...{
id: 2,
text: '兒子節點2',

children: [...{
id: 3,
text: '孫子節點',
leaf: true
}]
}]

下面是樹的顯示結果:

再比如GridPanel,用于顯示表格數據,GridPanel控件使用Store來存放表格中的數據,而Ext中的Store通過DataReader來解析數據,不同的DataReader可以解析不同的數據,因此在使用表格的時候,根據客戶端使用的DataReader不同,服務器端需要返回相應格式的數據。假如我們使用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:"開發團隊",dataIndex:"organization",sortable:true},

...{header:"網址",dataIndex:"homepage" }]);

var grid = new Ext.grid.GridPanel(...{
renderTo:"hello",
title:"中國Java開源產品及團隊",
height:200,
width:600,
cm:colM,
store:store,
autoExpandColumn:2
});
store.load();
});

這里要求服務器端返回類似下面的xml數據:
<?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的處理,還是控件的交互,他們在訪問服務器端的時候,90%都是通過使用Ext.Ajax.request方法來進行的,該方法可以用來向服務器端發送一個http請求,并可以在回調函數中處理返回的結果。往遠程服務器發送一個HTTP請求,發送Ajax調用的時候該方法的簽名如下:
Ext.Ajax.rquest( [Object options] ) : Number
服務器的響應是異步的,因此需要在回調函數中處理服務器端返回的數據。回調函數可以定義在request方法調用的參數options中。另外,在request方法中可以定義Ajax請求的一些其它屬性。參數options是一個對象,該對象包含了Ajax請求所需的各種參數及回調處理參數等。options中可以包含的各個屬性及含義如下所示:
url String 指定要請求的服務器端url,默認值為Ajax對象中配置的URL參數值。
params Object/String/Function 指定要傳遞的參數,可以是一個包含參數名稱及值的對象,也可以是name=xx&birthday=1978-1-1類似的url編碼字符串,或者是一個能返回上述兩種內容的函數。
method String 指定發送Ajax請求使用的method,可以是GET或POST方式。默認情況下,如果請求中沒有傳遞任何參數則使用GET,否則使用POST。
callback Function 指定Ajax請求的回調函數,該函數不管是調用成功或失敗,都會執行。傳遞給回調函數的參數有三個,第一個options表示執行request方法時的參數,第二個success表示請求是否成功,第三個參數response表示用來執行Ajax請求的XMLHttpRequest 對象。關于XMLHttpRequest可以通過http://www.w3.org/TR/XMLHttpRequest/查詢詳細的信息。
success Function 指定當Ajax請求執行成功后執行的回調函數,傳遞給回調函數兩個參數,第一個參數response表示執行Ajax請求的XMLHttpRequet對象,第二個參數表示執行request方法時的options對象。
failure Function 指定當請求出現錯誤時執行的回調函數,傳遞給回調函數兩個參數,第一個參數response表示執行Ajax請求的XMLHttpRequet對象,第二個參數表示執行request方法時的options對象。
scope Object 指定回調函數的作用域,默認為瀏覽器window。
form Object/String 指定要提交的表單id或表單數據對象。
isUpload Boolean 指定要提交的表單是否是文件上傳表單,默認情況下會自動檢查。
headers Object 指定請求的Header信息。
xmlData Object 指定用于發送給服務器的xml文檔,如果指定了該屬性則其它地方設置的參數將無效。
jsonData Object/String 指定需要發送給服務器端的JSON數據。如果指定了該屬性則其它的地方設置的要發送的參數值將無效。
disableCaching Boolean 是否禁止cache。
比如,下面是一個向服務器foo.ejf這個應用程序發起一個Ajax請求的應用示例程序:

function successFn(response,options)...{
alert('請求成功了');
}

function failureFn(response,options)...{
alert('請求失敗了');
}


Ext.Ajax.request(...{
url: 'foo.ejf',
success: successFn,
failure: failureFn,

params: ...{ foo: 'bar' }
});


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

function successFn(response,options)...{
var obj= Ext.decode(response.responseText) ;
alert(obj.username);
}
Ext.Ajax.request是Ext與服務器端交互的核心,因此需要在應用中靈活使用。在下一篇文章中,我會對Ext應用中的服務器程序作介紹。本文的文字、代碼及圖片等均來源于《ExtJS實用開發指南》,版權歸原作者所有,該指南當前在北京、深圳、成都、重慶、沈陽、杭州、上海等城市均已經可以直接到服務點購買,具體聯系方式:http://www.vifir.com/stations.html。)。
posted on 2008-04-02 09:44
簡易java框架 閱讀(4772)
評論(2) 編輯 收藏