当柳上原的风吹向天际的时候...

真正的快乐来源于创造

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks

 

 

 

 

 

 

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

posted on 2012-02-29 10:32 何杨 阅读(270) 评论(0)  编辑  收藏 所属分类: Teambiz

只有注册用户登录后才能发表评论。


网站导航: