Ajax中代码的重构

来源:互联网 发布:人工智能绝对龙头股 编辑:程序博客网 时间:2024/05/29 17:51

以前我们讲解了关于ajax的基础知识,了解到怎样操作DOM、加载一个文档等。如果你不打算去做一个ajax的大型代码库,你可以不用理会该小节的内容。因为这是对于维护大型的代码库所必须的。

重构refactoring:下面我们讲解一下关于Ajax中关于代码的重构的问题,首先我们要清楚,重构的作用和目的:第一,重构不是增加新的代码,而是重写代码使它们变得更加清晰,易于维护;第二,重构是识别出通用的解决方案,并按照这种特定的模式来重新组织代码的过程。

既然是使代码易于维护和修改,正原理在我们的编程中非常常见的,就向我们在C#.net中为了输出一个alert框,我们会写这样一个函数:

protected void ShowMessage(string msg)
{
       response.write(
""<script>alert('"+msg+"');</script>);
}

然后我们会在用到的地方直接引用该函数,例如:

{
 
if(dr.Read())
{
ShowMessage(
"登陆成功!");
Response.Write(
"<script>location="Passport.aspx"</script>");
}

}
 


道理是一样的,我们重构的过程就是封装原有的函数集成为一个整体,其在功能或引用方面具有一定的关系,当然我们这里的重构会有一定的区别,这与JavaScript语言的基本特征是分不开的。下面我们来看一下上一节加载文档的例子的重构过程及其代码:

既然我们要重构这代码,使其用起来的时候可以直接引用,那么我们就必须把起封装起来,这里我们使用“名字空间对象”,也就是我们C# 中所说的 namespace命名空间。

首先我们来声明命名空间对象: var net=new object();
接着我们来定义该命名空间内的全局变量:
net.READY_STATE_UNINTIALIZED=0;
net.READY_STATE_LOADING=1;
net.READY_STATE_LOADED=2;
net.READY_STATE_INTERACTIVE=3;
net.READY_STATE_COMPLETE=4;
其次,我们来说一下,onload、onerror是 Function对象,也就是说,它们是函数对象。上节说过,在我们的函数,sendRequest(url,params,HttpMethod)中,只有第一个是必须的参数,因为url包含着我们所要加载的数据的来源地址。params我们完全可以不传,即可以为null;HttpMethod默认的为"POST"方式,这里我们要来修改以下为“GET”。现在我们先来构造一个函数,当然也要属于net 命名空间。
net.ContentLoader=function(url,onload,onerror){                //声明net空间下的一个函数 ContentLoader
this.url=url;   //将数据来源变量值赋给该函数内的 this.url变量
this.req=null; //声明空的XMLHttpRequset对象
this.onload=onload; 
this.onerror=(onerror)?onerror:this.defaultError;
this.loadXMLDoc(url);
}
下面来构造请求的过程:
创建XMLHttpRequest对象,loadXMLDoc(url){};
发送信息对象:sendRequest(){};
请求状态监视对象:onReadyState(){};
默认错误处理对象:defaultError(){};
现在我们想了,上面的4个函数都会与net.ContentLoader中的变量定义有关,那我们怎么来重构这4个函数呢?
方法也不难,我们可以创建 net.ContentLoader的一个属性,就象我们可以给net创建了一个ContentLoader对象一样。下面我们来重构这4个函数:

net.ContentLoader.prototype={
loadXMLDoc:function(url){},
sendRequest:function(){},
onReadyState:function(){},
defaultError:function(){}
}

函数的重构到这里就结束了,可我们怎么获得加载的文档的内容呢?也就是说,我们到底有没有成功地加载数据呢?我们下面来把获得的内容输出来做下验证吧。


<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    
<title>无标题页</title>
    
<script type="text/javascript" src="ContentLoader.js"></script>
    
<script type="text/javascript">
    
function myCallBack()
    
{
        
var contentloader=document.getElementById("ContentLoader");
        contentloader.innerHTML
=this.req.responseText;
        
//var data=document.createTextNode(this.req.responseText);
        //contentloader.appendChild(data);
    }

    window.onload
=function()
    
{
        
var loader=new net.ContentLoader("data.txt",myCallBack);
    }
   
    
</script>
</head>
<body>
    
<form id="form1" runat="server">
    
<div id="ContentLoader">
    
    
</div>
    
</form>
</body>
</html>

上面代码中的myCallBack函数是回调处理函数。
关于重构我们就先讲到这里了,如果你不打算去做或者管理一个ajax的大型代码库,你可以不用理会该小节的内容。因为这是对于维护大型的代码库所必须的。下面我们附加完整的重构后的代码:

前台代码就是上面的一段了,下面附加 ContentLoader.js的代码内容:

var net=new Object();

net.READY_STATE_UNINITIALIZED
=0;
net.READY_STATE_LOADING
=1;
net.READY_STATE_LOADED
=2;
net.READY_STATE_INTERACTIVE
=3;
net.READY_STATE_COMPLETE
=4;


/*--- content loader object for cross-browser requests ---*/
net.ContentLoader
=function(url,onload,onerror,method,params,contentType){
  
this.req=null;
  
this.onload=onload;
  
this.onerror=(onerror) ? onerror : this.defaultError;
  
this.loadXMLDoc(url,method,params,contentType);
}


net.ContentLoader.prototype.loadXMLDoc
=function(url,method,params,contentType){
  
if (!method){
    method
="GET";
  }

  
if (!contentType && method=="POST"){
    contentType
='application/x-www-form-urlencoded';
  }

  
if (window.XMLHttpRequest){
    
this.req=new XMLHttpRequest();
  }
 else if (window.ActiveXObject){
    
this.req=new ActiveXObject("Microsoft.XMLHTTP");
  }

  
if (this.req){
    
try{
      
var loader=this;
      
this.req.onreadystatechange=function(){
        net.ContentLoader.onReadyState.call(loader);
      }

      
this.req.open(method,url,true);
      
if (contentType){
        
this.req.setRequestHeader('Content-Type', contentType);
      }

      
this.req.send(params);
    }
catch (err){
      
this.onerror.call(this);
    }

  }

}



net.ContentLoader.onReadyState
=function(){
  
var req=this.req;
  
var ready=req.readyState;
  
var httpStatus=req.status;
  
if (ready==net.READY_STATE_COMPLETE){
    
if (httpStatus==200 || httpStatus==0){
      
this.onload.call(this);
    }
else{
      
this.onerror.call(this);
    }

  }

}


net.ContentLoader.prototype.defaultError
=function(){
  alert(
"error fetching data!"
    
+" readyState:"+this.req.readyState
    
+" status: "+this.req.status
    
+" headers: "+this.req.getAllResponseHeaders());
}

下一节我们来讲解关于模式的问题。