Community Server系列之五:CS2中的Ajax原理

上一节用了一个示例说明了AjaxCS2中的一点简单的应用,这一节里着重探讨一下CS2中的Ajax的高级应用和实现原理,在了解Ajax的实现原理前我觉得有必要先了解一下aspx页面从请求到返回HTML都做了些什么,我想在了解了页面处理机制再来认识Ajax处理原理应该应该会很有帮助的,见下表:

序号

阶段

页面事件

可覆盖的方法

1

页面初始化

Init

 

2

加载视图状态

 

LoadViewState

3

处理回发数据

 

任意实现 IPostBackDataHandler 接口的控件中的 LoadPostData 方法

4

加载页面

Load

 

5

回发更改通知

 

任意实现 IPostBackDataHandler 接口的控件中的 RaisePostDataChangedEvent 方法

6

处理回发事件

由控件定义的任意回发事件

任意实现 IPostBackDataHandler 接口的控件中的 RaisePostBackEvent 方法

7

页面显示前阶段

PreRender

 

8

保存视图状态

 

SaveViewState

9

显示页面

 

Render

10

卸载页面

Unload

 

此表从上到下为处理ASPX页面所经历的过程,现简单解说一下各过程处理的工作:

1.              在页面实例化所有控件之后触发,页面的控件也仅仅是实例化好了,各静态变量也有了初始值,在这个事件里,一般我们可以设置一些事件处理程序等等。

2.              如果是回发那么加载视图状态。

3.              处理回发数据,为控件赋值,这里通过读取回发过来的数据初始化各控件的属性。这样,第一步生成的控件就会有值了。

4.              激发Load事件

5.              处理比如OnChange这样的事件,也就是控件属性和ViewState中的值不同的话,将会激发事件处理程序。

6.              处理页面里的按钮等回发事件。

7.              页面即将展现给用户,也就是即将生成HTML代码前激发的事件,注意这个地方是我们的Ajax关键事件,在这里页面前的初始化和相关事件都处理完了,服务器控件已经具有该有的值了,而Ajax应用只会返回给客户段一小部分HTML或字符串,作为客户端调用AjaxPostBack的返回值,显然此处不下手还等待何时呢,在这里,筛选出我们想要返回给客户端的对象并且只呈现这些对象即可,而执行完这些对象的Render方法之后即可停止Response数据了。

8.              保存视图状态,在aspx中视图状态保存在客户端HTML的隐藏字段__VIEWSTATE中。

9.              依次执行各个控件的Render方法,输出需要呈现的HTML标签,Render方法是asp.net中很关键的方法,每个服务器控件都有相应的Render方法,它的目的就是把自己生成HTML格式的字符串,此字符串最终返回给客户端的浏览器。

10.           最后一步触发卸载页面事件,我们可以在此处理资源回收等操作。

了解了此原理后,我想要理解Ajax的运行原理应该不是大问题了,让我们再了解一下Ajax都有哪些操作,我想不外乎两种方式,一种是不返回值或返回简单字符串形式,客户端通过这点标识操作一些功能,另外一种方式是返回HTML格式内容,比如在网页里的某个区块的动态加载内容,这两种方式大同小意,我们的Ajax在后台都是相似的处理,我想要说明处理过程还是结合示例来说比较通俗,现在就拿在CS2中经常用到的AjaxPager这个控件来说,这个控件在CS2中算是比较高级一点的应用了,与我们的第三方Ajax控件比较类似,使用方法既是在AjaxPager控件里嵌入相应的服务器控件(比如Repeater控件)以后就可以使里面的内容无刷新分页显示数据了,表面上看来是很高深很酷的功能,其实处理过程并不是想象中的那般复杂。

 

<CS:AjaxPager runat="Server" id="PostsPager" ShowFirstLastLinks="false">

                                                        
<asp:Repeater id="Posts" runat="Server" >

                                                               
<ItemTemplate>

                                                                      
<div class="CommonSidebarContentItem">

                                                                             
<asp:HyperLink Runat="server" id="TitleLink" />

                                                                      
</div>

                                                               
</ItemTemplate>

                                                        
</asp:Repeater>

                                                 
</CS:AjaxPager>

大致分析一下此控件的工作流程:此控件为分页控件,在页面加载的时候赋上分页属性,计算页数,并生成相应的Ajax分页连接,当用户点击分页连接的时候,页面在后台进行ajax提交,通过服务器处理后返回HTML形式的提交结果,并通过js脚本呈现到浏览器上。

AjaxPager

关键一点是让程序注册PreRender处理事件,我们知道,在此事件控件还没有生成HTML代码,也就是Response对象里还没有具体的HTML代码,所有的控件还没有执行Reader方法,这里我们就可以选择想执行Reader方法的控件而忽略其他控件,在此我们只需要执行包含在AjaxPager控件内的控件(也就是AjaxPager的子控件)的Reader方法, 这样就可以保证Response给客户端的是纯净的,只在AjaxPager控件内部的控件的HTML实现。

让我看看此控件重写的OnInit方法,此方法里的AjaxManager.Register(this, "AjaxPager");这一句在前面一章已经介绍过,为注册Ajax的回发脚本,当然它还有另外一个作用那就是注册PreRender事件,当触发PreReader事件 到时候,AjaxManager会去找控件里具有AjaxMethod属性的方法来执行,让我们看看在AjaxPager里的AjaxMethod都干了些什么:

 

[AjaxMethod(IncludeControlValuesWithCallBack=true)]

         
public virtual string GetPage(int page)

         
{

              StringWriter stringWriter 
= new StringWriter();

              HtmlTextWriter htmlWriter 
= new HtmlTextWriter(stringWriter);

 

              AddPageLinks();

              AddPreviousNextLinks();

 

              
if (this.ShowFirstLastLinks)

                   AddFirstLastLinks();

 

              
this.Render(htmlWriter, false);

 

              
return stringWriter.ToString();

          }


可以看出,倒数第二句就是Reader方法,输出的HTML保存到HtmlTextWriter中,最后一句即是把控件的HTML呈现字符串对象返回给调用者(这里指的是AjaxManager),AjaxManager获得值后按照指定的格式Response到客户端,并中止其他的Response,客户端通过调用document.getElementById(‘’).innerHTML = result.value来向浏览器呈现指定区域的数据。

posted on 2006-04-26 20:12  dragonpro  阅读(4120)  评论(10编辑  收藏  举报

Free Web Counter