前一段做项目的时候,要用到异步加载数据的知识。以前没写过这方面的,查了查,可以使用Ajax来完成。有很多现成额Ajax框架,但是总感觉用这些东西之前至少得先把原理弄清楚吧。在者,用那些别人的控件的时候,出个问题调bug就是个令人纠结头疼的事,就是因为自己根本不明白底层到底是怎么回事。。。。

好吧,然后就开始最基础的XMlHttp对象的学习。

这里,暂时抛开令人郁闷的浏览器兼容的问题。免得将过多的精力放在那上边。

说实话,很少写js,这次算是写的比较多的了。

 

什么是Ajax?

W3c说AJAX 指异步 JavaScript 及 XML(Asynchronous JavaScript And XML),其实或许有些概念性的东西,用的多,自然就明白了。

 

首先说一下自己做的demo吧。

在DataList中(描述不准确,大家应该都明白吧)点击链接,异步加载数据,展示到页面上。

 

在网上找了一些教程,看来不算复杂。

基本思路就是

创建XMlHttp对象,利用XMlHttp对象异步请求某个文件,获取文件内容,触发定义好的事件,改变客户端内容。

那么需要一个显示数据的页面,叫Default.aspx,然后还有一个处理数据的页面,接受参数,返回数据,叫做Data.asxp. ok,这两个就够了。

对于页面代码主要就是 做了一个DataLIst ,后台绑定几个测试用的数据。

其中lblFileData是用来显示数据的,当然显示之前,给出的是友好的提示。注册了一个js事件,用于点击时进行响应,将当前的对象和路径信息传递过去(抽象来说就是 1. 当前对象2. 数据参数信息)

代码如下

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
 <asp:DataList ID="dlShowData" runat="server">
 <ItemTemplate>
   <table>
   <tr>
     <td  class="title">文件编号:</td>
     <td ><%#Eval("编号") %></td>
   </tr>
    <tr>
10     <td class="title">文件信息 :</td>
11     <td><label   class="lblclick"  id="lblFileData" onclick=' showData(this , " &lt;%#Eval("路径" ) %>" )'&gt; 点击查看文件信息</label><br/></td>
12     </tr>
13     <tr>
14         <td class="title">文件名称:</td>
15         <td><%#Eval("名称")%></td>
16     </tr>
17    </table>
18  </ItemTemplate>
19  </asp:DataList>
20 </asp:Content>

接下来是js代码

createXmlHttp函数 用来创建XmlHttp对象,由于浏览器兼容问题,做了一点小处理。其实可以处理的更好一点,这里就不麻烦了。

sendReqest 利用XMlHttp发送请求。

getReqUrl 获得我们所需要的Url

showData 毫无疑问,点击时异步获得数据,并改变页面显示内容。

代码如下(包括部分css)

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
<style type="text/css">
    .title
    {
        width:150;
    }
    .lblclick
    {
        cursor:pointer;
10         color:Blue;
11         text-decoration:underline;
12     }
13     .data
14     {
15         color:Black;
16         text-decoration:none;
17         cursor:auto;
18     }
19 </style>
20 <script type="text/javascript">
21     function showData(lblFileData, path) {
22         var xmlHttp = createXmlHttp();
23         if (xmlHttp) {
24             //在xmlHttp对象状态发生改变是会自动触发该函数,和.net中的事件模型一样。
25          //状态有好几种,4 表示数据接收完毕,200表示请求已处理成功
26             xmlHttp.onreadystatechange = function () {
27                 if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
28                     lblFileData.innerText = xmlHttp.responseText;
29                 }
30                 else if (xmlHttp.readyState != 4) {
31                     lblFileData.innerText = "数据加载中……";
32                 }
33                 else if (xmlHttp.readyState == 4 && xmlHttp.status != 200) {
34                     lblFileData.innerText = "数据加载已完成,但是未得到相应数据!";
35                 }
36                 else {
37                     lblFileData.innerText = "请求错误,返回错误编号" + xmlHttp.status;
38                 }
39                 lblFileData.className = "data";
40             }
41         }
42         lblFileData.className = "data";
43         var reqUrl = getReqUrl(path);
44         sendReqest(xmlHttp,reqUrl);//发送请求
45     }
46
47     //创建xmlHttp对象
48     function createXmlHttp() {
49         var xmlHttp = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
50         return xmlHttp;
51     }
52
53     function sendReqest(xmlHttp, url) {
54         //有三种方式GET,POST,HEAD,不同的方式稍微有点不同,url即为请求的文件路径,一定不要写错。。。true表示异步请求
55         xmlHttp.open("GET", url, true);//打开请求
56         xmlHttp.send();//发送请求
57     }
58
59     //有中文,会出项乱码,采用二次编码,在接收端进行二次解码。。不知道有没有更好的处理办法
60     function getReqUrl(path) {
61         path = encodeURI(encodeURI(path));
62         var url = ".\\Data.aspx?path=" + path;
63         return url;
64     }
65
66 </script>
67 </asp:Content> 

对于一些细节问题,比如说那些状态各代表什么意思啊,什么的,童鞋们自己查查吧

 

后台代码如下

 
protected void Page_Load(object sender, EventArgs e)
    {
        if(!Page.IsPostBack)
        {
            DataTable dataTable = GetDataSource();
            BindData(dataTable);
        }
    }

10     protected void BindData(DataTable source)
11     {
12         dlShowData.DataSource = source;
13         dlShowData.DataBind();
14     }
15
16     protected  DataTable GetDataSource()
17     {
18         DataTable dataTable=new DataTable();
19         dataTable.Columns.Add("编号");
20         dataTable.Columns.Add("路径");
21         dataTable.Columns.Add("名称");
22         
23         string[] pathes=new string[]{"F:\\ASP.NET\\MyCode\\MyBlog\\XmlHttp-2011-7-24\\Data\\extern学习.txt",@"F:\\ASP.NET\\MyCode\\MyBlog\\XmlHttp-2011-7-24\\Data\\编程风格类.txt",@"F:\\ASP.NET\\MyCode\\MyBlog\\XmlHttp-2011-7-24\\Data\\堆与栈.txt"};
24         string[] names=new string[]{ @"extern学习.txt",@"编程风格类.txt",@"堆与栈.txt" };
25         dataTable.Rows.Add(1, pathes[0], names[0]);
26         dataTable.Rows.Add(1, pathes[1], names[1]);
27         dataTable.Rows.Add(1, pathes[2], names[2]);
28
29         return dataTable;
30     }
接下来就是Data页面了这个页面很简单,就是获得传递过来的参数,访问本地文件,得到数据后,写到Response响应流中。

代码如下

 

protected void Page_Load(object sender, EventArgs e)
    {
        string path = Page.Request.QueryString["path"];
        path = Server.UrlDecode(path);
        string responseText = "";
        if(!string.IsNullOrEmpty(path))
           responseText= GetData(path);
        else
            responseText = "文件路径信息错误!";
10         Response.Write(responseText);
11         Response.Flush();
12     }
13
14     /// <summary>
15     /// 获取数据源
16     /// </summary>
17     /// <param name="path"></param>
18     /// <returns></returns>
19     protected  string  GetData(string  path)
20     {
21         return GetFileContent(path);
22     }
23
24     /// <summary>
25     /// 得到文件内容信息
26     /// </summary>
27     /// <param name="path"></param>
28     /// <returns></returns>
29     protected  string GetFileContent(string  path)
30     {
31         if(File.Exists(path))
32         {
33             StreamReader sr= new StreamReader(path,Encoding.Default);
34             string content= sr.ReadToEnd();
35             sr.Close();
36             return content;
37         }
38         else
39         {
40             return "没有找到对应文件信息";
41         }
42     }
OK,这样下来这个Demo就完成了。这样的话,以前的RCenter中回复事件注册为后台事件响应极慢的问题应该就很容易解决了吧,只不过是更改一下数据源,调整优化样式的事情了。

 

回想一下真个编写过程,也不是很顺利的,调试了好几次才搞定。最多的问题处在路径上,在onclick中传递单斜杠到js方法中时,单斜杠被消除了,是转译么?还没有细细研究,现在的处理是在后台传递时传递双斜杠,这样就没问题了。

源码地址   http://dl.dbank.com/c0beaw4hbn