RoyalAjax(二),对HttpRequest的封装

要成功利用Ajax的异步性优势,就必须为每个HttpRequest注册独立的处理函数,而为了使javascript代码可被java程序生成,必须为每个处理函数命名,在这一点上,面向对象的包或命名空间的概念为我们提供了很好的参考。

可以直接延用这一规则,于是想到了javascript的面向对象特性。现在考虑一个类Ajax,其封装了HttpRequest。在这一实现上,一般将HttpRequest作为Ajax类的一个域req,对每个Ajax实例ajaxObject,为其域ajaxObject.req注册onstatechange处理函数,该函数最好是ajaxObject的一个function域或void行为。于是想到了下面的语句:

Ajax.prototype.submit=function(){
 this.status="ready";
 this.req.onreadystatechange = this.processRequest;
 this.req.open("GET",this.url,true);
 this.req.send(this.body);
}

Ajax.prototype.processRequest=function(){
process(this);
}

但这是行不通的,因为processRequest此时仅仅是一个函数的引用,它没有this这个对象了。

那么如何解决这个问题呢?

Ruby使用了一系列复杂的对象使Ajax类能够绑定(bind)this,使this能作为参数传入processRequest,但个人认为作为一个公用模块尽量不要使用如此多的限定(类继承关系复杂)。

我的解决方法是用一个池(AjaxFactory)来生成并维护一组Ajax实例,每个Ajax实例有一个唯一的name,于是可以通过自己的name到AjaxFactory中取得对自己的引用。

下面是AjaxFactory的源程序:

/*
*
*
*AjaxFactory,负责生产并维护Ajax类实例
*
*
*/
function DefaultAjaxFactory(){
 this.map=new Map();
}
DefaultAjaxFactory.prototype.createAjax=function(name){
 var ajax=new Ajax(name);
 this.map.put(name,ajax);
 return ajax; 
}
DefaultAjaxFactory.prototype.getAjax=function(name){
 return this.map.get(name);
}

其中Map的使用类似于java的java.util.HashMap,关于Map等数据结构的类请看我的其他文章。

程序在使用的时候可以这样写:

var AjaxFactory=new DefaultAjaxFactory();
var ajaxObject=AjaxFactory.createAjax("ajaxObject");

这样就生成了一个Ajax的实例ajaxObject。

下面是Ajax的实现:

/*
*
*
*Ajax ,异步化提交一个请求并获得结果(对象或数组)
*
*
*/
function Ajax(name){
 this.req=new ActiveXObject("Msxml2.XMLHTTP");
 this.name=name;
 this.xmlDoc=null;
 this.status="ready";
 this.url="";
 this.body="";
 this.doSuccess=function(){return null;};
 this.doFail=function(){return null;};
 this.object=new XMLObject();
}
Ajax.prototype.submit=function(){
 this.status="ready";
 //注意这一句,这就是注册statechange处理函数的语句
 this.req.onreadystatechange = new Function("var temp_ajax=AjaxFactory.getAjax(/""+this.name+"/");temp_ajax.processResponse()");
 this.req.open("GET",this.url,true);
 this.req.send(this.body);
}
Ajax.prototype.processResponse=function(){
 if(this.req.readyState==4){
  if(this.req.status==200){
   this.status="success";
   this.preHandleSuccess();
   this.doSuccess();
  }else{
   this.status="fail";
   this.preHandleFail();
   this.doFail();
  }
 }
}
Ajax.prototype.setSuccessHandler=function(successFunc){
 this.doSuccess=successFunc;
}
Ajax.prototype.setFailHandler=function(failFunc){
}
Ajax.prototype.preHandleSuccess=function(){
 //fire after process succeeded
 var xmlDoc=this.req.responseXML.getElementsByTagName("Object")[0];
 this.visitTree(xmlDoc);
}
Ajax.prototype.preHandleFail=function(){
 //fire after process failed
}
Ajax.prototype.visitTree=function(root){//遍历node tree将xml nodes转换为javascript对象
 if(root.hasChildNodes){
  objname=root.tagName;
  this.object.addProperty(objname);
  for(var i=0;i<root.childNodes.length;i++){
   var node=root.childNodes[i];
   this.visitTree(node);
  }
 }else{
  var objvalue=root.nodeValue;
  this.object.setProperty(objvalue);
 }
}
/*for it is not synchronized,please call the following functions in your success handlers*/
Ajax.prototype.getObject=function(){
 return this.object.Object[0];
}
Ajax.prototype.getQuery=function(){
 var obj=this.getObject();
 var res=new Array();
 return res;
}
/*               end               */

 

 

/*usage:
function ss(){//成功处理函数
 var obj=this.getObject();
}
var ajax=AjaxFactory.createAjax("abc1");
ajax.url="http://localhost:8080/UserAdmin/servlet/AjaxDispatcher?DspId=999999";
ajax.setSuccessHandler(ss);//注册处理函数
ajax.submit();
*/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值