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解析异常,但对此无需过于担心,需要注意的多在备注这样的字段中,可以在需要特殊处理再进行处理。