随笔-80  评论-383  文章-17  trackbacks-7

上一节用了一个示例说明了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 阅读(3445) 评论(11)  编辑 收藏 网摘 所属分类: 编程/技术

评论:
#1楼  2006-04-27 10:24 | Konimeter      
不错
  回复  引用  查看    
#2楼  2006-04-27 10:42 | xpengfee [未注册用户]
小弟初试Ajax,对大侠甚是佩服。大侠可否将AjaxPager控件的完整源码不吝赐小弟一份,谢谢! xpengfee@163.com
  回复  引用    
#3楼  2006-04-27 18:17 | jillzhang1 [未注册用户]
请问你的 cs 2。0在那里下载的亚?

  回复  引用    
#4楼  2006-04-27 21:44 | Felix.Net      
@Download
www.communityserver.org

  回复  引用  查看    
#5楼  2006-05-25 17:32 | 思无邪      
应该是任意实现 IPostBackEventHandler接口的控件中的 RaisePostBackEvent 方法

public interface IPostBackEventHandler
{
// Methods
void RaisePostBackEvent(string eventArgument);
}

  回复  引用  查看    
#6楼  2006-07-03 23:36 | gjwj [未注册用户]
GetPage(int page) 中的INT PAGE 有什么作用啊?调试的使用看好象是PAGEINDEX的值,但怎么调用的和使用的一直不知道.....
  回复  引用    
#7楼 [楼主] 2006-07-10 01:56 | Felix      
@gjwj
就是分页的索引啊

  回复  引用  查看    
#8楼  2006-11-09 23:08 | kudo[匿名] [未注册用户]
接上:GetPage(int page) 中的INT PAGE 有什么作用啊?

虽然我们知道INT PAGE 是分页索引,但似乎没有什么地方调用过它,不知是不是?

我奇怪的是Repeater组件它是怎么取得这个索引的?


  回复  引用    
#9楼  2008-02-21 11:41 | BAsil      
请问 这个是在哪个版本里的阿,我看了CS 2.1 ,有AjaxPager这个类,但是任何地方都没有用到阿?
  回复  引用  查看    
#10楼  2008-02-21 16:23 | BAsil      
我试了一下,要想上面的代码工作,GetPage方法必须改为
this.PageIndex=page-1;
StringWriter stringWriter = new StringWriter();
HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);

AddPageLinks();
AddPreviousNextLinks();

if (this.ShowFirstLastLinks)
AddFirstLastLinks();
//this.Parent.DataBind();
this.Page.DataBind();
this.Render(htmlWriter, false);

return stringWriter.ToString();

  回复  引用  查看    

发表评论



姓名 [登录] [注册] 
主页
Email (仅博主可见) 
验证码 *  验证码看不清,换一张
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论   新用户注册   返回页首      

导航: 网站首页 社区 新闻 博问 闪存 网摘 招聘 .NET频道 知识库 找找看 Google站内搜索



China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
China-Pub 计算机绝版图书按需印刷服务

相关文章:

相关链接:
 
Free Web Counter