如果看過yui-ext的例子,相信大家很想把它用在實際項目中去,我這兩個星期都在研究它,國內幾乎沒有資料,只能從http://www.jackslocum.com的論壇找,我現在簡單介紹一下我的實際開發環境:
我的項目原來的開發環境是Struts+Spring1.2.8+Hibernate3.1.2,現在要把頁面的jsp+jstl,和Struts的Action轉換成yui-ext的Ajax頁面,簡單實現資料列表、翻頁和添加、修改、刪除等功能。
1.
資料交換,要從Struts環境的Action通過request對象傳遞資料給jsp頁面,如果用Ajax,比較常用的是XML轉換和Json轉換,我
選擇了Json,因為用json-lib包可以在java端用很方便的把對象轉換成Json格式,在頁面可以呼叫指令碼eval()轉換成
javascript的數組對象。
1) json-lib轉換java對象(下載json-lib:http://json-lib.sourceforge.net)
Action例子:(example.do)代碼中加入:
response.setContentType("text/xml;charset=utf-8");
JSONArray jsonArray = JSONArray.fromObject(list);
response.getWriter().print("{datalist:" + jsonArray + "}");
return null;
簡單說明:把action的return mapping改成null,因為現在使用response對象進行資料傳遞,fromObject(list)中的list包括就是頁面需要調用顯示的資料,可以是其他java對象,String、bean或Map。
2) JSONDataModel調用Action(example.do)
yui-ext通過JSONDataModel.js把json格式轉換成javascript的數組對象
js例子:
var schema = {
root: 'datalist',
id: 'nothing',
fields: ['a','b', 'c', 'd']
dataModel= new YAHOO.ext.grid.JSONDataModel(schema);
dataModel.load('http://xxx/example.do');
說明:schema的root參數要和action傳遞的json資料頭list對應,這裡new
JSONDataModel後,JSONDataModel會把example.do返回的json資料轉換成dataModel的數
組,JSONDataModel繼承於LoadableDataModel,JSONDataModel只複雜轉換json資料,其他由繼承的類實現,這
是yui-ext的特點,你可以自己寫DataModel繼承父類,轉換自己的資料格式,yui-ext提供了JSONDataModel和
XMLDataModel兩種資料格式轉換。
3) 使用grid顯示dataModel資料
js例子:
var grid = new YAHOO.ext.grid.Grid('example-grid', dataModel, colModel);
grid.render();
jsp頁面例子:
<div id="example-grid" style="border: 1px solid #cccccc;
overflow: hidden; width: 535px; height: 225px;"></div>
說明:colModel的使用看example,grid綁定dataModel後,在頁面的<Div>顯示grid。
大家一定會給yui-ext的EditorGrid可編輯表格吸引,但編輯後怎麼提交到後台Action?我也曾經苦惱了一段時間,在
http://www.jackslocum.com/forum的論壇,jack
sloc說過,如果使用XMLDataModel,你在grid編輯修改後,XMLDataModel中的資料也會同時修改,只要把
XMLDataModel的資料產生xml提交後台就可以了,我在項目中沒有實現XMLDataModel的xml傳輸,沒驗證他的說法,因為我找不到很
好的java對象轉換xml格式的包,希望網友有好的包介紹一下。
而我選擇了JSONDataModel,要實現把json格式提交到伺服器,jack
sloc提示要自己轉換json資料,暈,因為要在頁面使用js指令碼實現轉換,開始覺得很難,但實現後發現並不困難,以下介紹一下,本文有些內容是參考了
http://www.rodrigodiniz.qsh.eu/YahooGrid.aspx的grid例子:
1. 把dataModel資料回填Form中的元素
例子是實現把dataModel中的一行資料自動填到form表單的元素中,也就是替代struts的<html:XXX>標籤,這裡要告訴
大家,連jstl都不能用了,因為不用重新整理頁面,但還好,我還有點javascript基礎,jstl的一些功能還可以用js實現。
例子:
<form name="form1">
<input type="text" name="userId" value="">
<input type="text" name="userName" value="">
</form>
說明:隨便做一個簡單的form。
dataModel= new YAHOO.ext.grid.JSONDataModel(schema);
dataModel.addListener('load', onEditLoad);
dataModel.load('http://xxx/example2.do');
說明:在dataModel添加一個Listener,使用dataModel即時從後台example2.do取一個javabean對象new
User(userId,userName)的資料(example2.do的實現可參考第一部分Action介紹),javabean資料返回後啟用
onEditLoad()方法,yui-ext使用一般使用callback得到回調資料,待會兒介紹。
function onEditLoad() {
var row = dataModel.getRows([0,0]);
var fields=dataModel.schema.fields;
for(var i=0;i< fields.length;i++){
if ($(fields[i])!= null) {
$(fields[i]).value= row[0][i];
}
}
}
說明:
因為返回是一個javabean,JSONDataModel已經轉換成javascript數組對象,所以getRows([0,0]只取第一行資料
[object1,object2],object1中包括userId=XXX,object2包括userName=XXX,在schema取出與
javabean對應的fields數組[userId,userName),
這裡用到prototype.js,網上很容易找到,它通過$(fields[i])調用form表單中的元素,其
實$(fields[i])=document.getElementById(fields[i])),通過迴圈就可以把dataModel資料自動填
到form表單元素。
2. 頁面提交表單方法一:
使用prototype.js把form元素通過Form.serialize()方法自動調交後台,Action以request.getParameter("xxx")擷取資料。例子如下:
function Save(){
var callback = {
success : responseSuccess,
failure : responseFailure
};
var postData=Form.serialize($("form1"));
YAHOO.util.Connect.asyncRequest('POST', "http://xxx/example3.do", hcallback, postData);
}
var responseSuccess = function(o)
{
alert(o.responseText);
}
var responseFailure = function(o)
{
alert(o.statusText);
}
說明:建立一個callback方法,使用Yahoo
UI的asyncRequest()方法post資料到action,其原理就是在連結後面加參數,象http://xxx
/example3.do?userId=XXX&userName=XXX,後台action通過
request.getParameter("xxx")擷取資料,但缺點是要手工對建立user對象。
3. 頁面提交表單方法二:使用Json資料格式提交到後台Action
1)前台js指令碼例子:
function save() {
var fields=dataModel.schema.fields;
var objRet= new Object();
for(var i=0;i< fields.length;i++){
if ($(fields[i])!= null) {
objRet[fields[i]]=$(fields[i]).value;
}
var callback = {
success : responseSuccess,
failure : responseFailure
};
YAHOO.util.Connect.asyncRequest(
'POST',
'http://xxx/example3.do',
callback,
"outJSONXml=[" + YAHOO.ext.util.JSON.encode(objRet) + "]");
}
說明:通過dataModel的fields數組擷取對象名,建立一個Object()對象,存放form表單中元素的value,然後通過Yahoo UI的JSON.encode()方法轉換成json格式,其調交原理:
http://xxx/example3.do?outJSONXml=[---json資料格式---]
2) 後台Action(example3.do)接收json資料格式例子:
private BeanUtilsBean beanUtilsBean;
if (request.getParameter("outJSONXml")!=null) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("JSonParser",request.getParameter("outJSONXml"));
List list = JSONArray.toList( jsonObject.getJSONArray( "JSonParser" ) );
JSONDynaBean beana = (JSONDynaBean) list.get(0);
User user = new User();
beanUtilsBean.copyProperties(user,beana)
}
說明:因為JSONDynaBean對象是繼承於DynaBean,所以可以通過apache的common包中的BeanUtilsBean把對象自動從JSONDynaBean拷貝到user對象,這樣就省去了手工把對象逐一賦值的麻煩。
3) 關於updateManager()方法
yui-ext也提供一個updateManager方法,實現和Yahoo asyncRequest()方法一樣的功能,可以實現把後台反回的資訊填入一個<Div>提示使用者,例子如下:
var mgr = new YAHOO.ext.UpdateManager('errorDiv');
mgr.update('http://xxx/example3.do',
"outJSONXml=[" + YAHOO.ext.util.JSON.encode(objRet) + "]", );
updateManager使用callback回調:
mgr.update({
url: 'http://xxx/example3.do',
params: "outJSONXml=[" + YAHOO.ext.util.JSON.encode(objRet) + "]",
callback: updateString,
text: 'Loading...',
timeout: 10,
scripts: true
});
function updateString(oElement, bSuccess) {
if (bSuccess) {
alert(oElement.innerHTML);
}
}
總結:以上兩部分一口氣總結了我近兩個星期對yui-ext在實際項目中測試應用的情況,現在我還在項目範例工程測試中,有很多細節的地方在這裡沒有很詳
細的羅列,由於yui-ext介紹的例子有限,對於前後台應用介紹很少,所以特意把經驗寫出來讓大家少走彎路,共同研究,水平有限,請大家不要介意,請多
交流指點。