Teambiz中前臺頁面對XHR對象從后臺取回的XML的處理
作者:何楊
撰寫日期:2012年2月24日
版本:1.00
更新日期:2012年2月25日
第一部分:功能說明
XHR從后臺得到XML文本后,使用DOM對其進行解析。
第二部分:核心組件
名稱 | 路徑 | 說明 |
Ajax.Request | teambiz\WebRoot\page\js\prototype-1.6.0.3.js | Prototype提供的Ajax請求對象,它將被用來想后臺發出異步請求并獲取反饋。 |
ajaxObj | 無 | 它就是XMLHttpRequest對象(簡稱XHR)。 |
ajaxObj.responseText | 無 | XHR對象獲得的反饋文本,在需要查看反饋的XML時會用到它。 |
ajaxObj.responseXML | 無 | XHR對象獲得的反饋XML,也是前端需要解析的數據來源。 |
status | 無 | 反饋XML第一個status節點的值,當它為ok是意味著順利得到了后端傳來的信息;當它為ng意味著前后端通道是通暢的,但由于某種原因不能獲得想要的數據,這個原因可能是用戶缺乏權限,后端組件未準備好,后他SQL調用出現異常或是運行異常。這個變量需要在前后端有固定約定才能發揮功用。 |
arr | 無 | 包含反饋XML中所有node節點的數組。它也依賴于前后端有固定的約定。這是一個臨時變量,真正發揮功用的是tableDatas。 |
tableDatas | 無 | 它本身是一個數組,而內部元素也是一個數組,正如其名稱描述的那樣,它是一個表格形式的數據,它的“行”相當于SQL查詢結果集的行,它的“列”相對于結果集的字段值集合,它的“單元格”就是數據。 之所以采用這個對象是因為在使用上相對于arr更加方便,進行一次遍歷再通過數組下標就能訪問到每個數據。 |
第三部分:三種前臺對取回XML的處理
1.如果前臺僅需status一個量。
有時,前臺僅需status就能進行判定后臺是否實現了自己的目的,如進行登錄,變更等操作,對status直接進行判斷即可,對后臺進行CUD操作常會這樣處理,示例代碼如下:
new Ajax.Request(url,{
method:'get',
onSuccess: function(ajaxObj){
// alert(ajaxObj.responseText);
hideLoadingWnd();
var status=ajaxObj.responseXML.getElementsByTagName("status")[0].firstChild.data;
if(status=="ok"){
window.location.href="Goto.do?page=/page/jsp/task/tododone/index.jsp";
}
else{
// 返回錯誤信息
hideLoadingWnd();
var text=ajaxObj.responseXML.getElementsByTagName("text")[0].firstChild.data;
alert(text);
}
},
onFailure: function(){
hideLoadingWnd();
alert("服務器沒有響應.");
}
}
);
以上代碼所在路徑:teambiz\WebRoot\page\jsp\user\login\javascript.jsp中submitForm函數。
2.如果前臺需要按照節點名稱取出傳回XML的值。
有時,前臺需要明確取出某個名稱的節點值(意圖獲得后臺處理的狀態),這時可以如同取出status的值一樣,從ajaxObj中取出想要的值,示例代碼如下:
var currentPage=ajaxObj.responseXML.getElementsByTagName("currentPage")[0].firstChild.data;
var recordCount=ajaxObj.responseXML.getElementsByTagName("recordCount")[0].firstChild.data;
var pageCount=ajaxObj.responseXML.getElementsByTagName("pageCount")[0].firstChild.data;
// 設置分頁數據
setPage(recordCount,currentPage,pageCount);
以上代碼路徑:teambiz\WebRoot\page\jsp\task\sent\javascript.jsp中search函數。
3.如果前臺需要表格形式的數據
對后臺的查詢操作常進行這種處理,這時需要用到系統轉化出來的tableDatas對象,示例代碼如下:
/*****************************************************
* 取得后方菜單
* 何楊,2012年2月7日11:40:34
*****************************************************/
function fetchMenuFromBg(){
$("menuBar").innerHTML="";
// 組合URL
var url=encodeURI('FetchMenu.do?');
url=encodeURI(url);
// 發出Ajax請求
new Ajax.Request(url,{
method:'get',
onSuccess: function(ajaxObj){
// alert(ajaxObj.responseText);
var status=ajaxObj.responseXML.getElementsByTagName("status")[0].firstChild.data;
if(status=="ok"){
// 找到所有節點放入數組
var arr=ajaxObj.responseXML.getElementsByTagName("node");
if(arr.length==0){
alert("沒有得到返回數據.");
}
var tableDatas=new Array();
// 遍歷這個數組
for(var i=0;i<arr.length;i++){
var node=arr[i];
var arr2=new Array();
for(var j=0;j<node.childNodes.length;j++){
var child=node.childNodes.item(j); arr2.push(child.childNodes[0].nodeValue);
}
// 向表格中添加行
tableDatas.push(arr2);
}
// 顯示菜單
showMenu(tableDatas);
}
else{
var text=ajaxObj.responseXML.getElementsByTagName("text")[0].firstChild.data;
alert(text);
}
},
onFailure: function(){
hideLoadingWnd();
alert("服務器沒有響應.");
}
}
);
};
/*****************************************************
* 顯示菜單
* 何楊,2012年2月7日14:03:43
*****************************************************/
function showMenu(tableDatas){
var ul=document.createElement("ul");
for(var i=0;i<tableDatas.length;i++){
var arr=tableDatas[i];
var text=arr[0];
var url=arr[1];
var link=document.createElement("a");
link.appendChild(document.createTextNode(text));
link.setAttribute("href", url);
var li=document.createElement("li");
li.appendChild(link);
ul.appendChild(li);
}
$("menuBar").appendChild(ul);
}
以上代碼路徑:teambiz\WebRoot\page\js\common.js,其中tableDatas的產生用getTableDatasFromArr進行了一定程度的簡化。
第四部分:使用步驟
步驟 | 說明 | 參照 |
編寫向后端發起請求的函數 | 請參照上面的fetchMenuFromBg函數書寫新函數,主要需要修改的地方在URL和處理tableDatas的函數,其它部分無需變化。 | teambiz\WebRoot\page\js\common.js中的fetchMenuFromBg函數。 |
編寫處理tableDatas的函數(可選) | 遍歷方式請參照上面的showMenu函數,取得數據后進行DOM操作需要自行處理。 | teambiz\WebRoot\page\js\common.js中的showMenu函數。 |
第五部分:小結
在前后臺有一定約定的前提下(status,node),通過一系列對象的配合,我們輕松完成從SQL查詢結果集到前臺能使用的結果集的轉換,這些對象及其使用方法絕大多數都是固定的或是僅需稍加改變的,程序員主要需要考慮的是最初的SQL語句和最終的DOM處理過程,中間只用按部就班的完成裝配工作。
這種方式的優勢在于:
1.減輕了編碼量,同時也減少了出錯的可能。
2.易用,因為SQL相對于HQL更容易被人接受。
3.比頁面循環標簽更具表現性。
這種方式的主要缺點在于:
1. JS和DOM操作需要程序員加以小心。
2.如果字段含有特殊字符可能會造成XML解析異常,但對此無需過于擔心,需要注意的多在備注這樣的字段中,可以在需要特殊處理再進行處理。