ASP.NET AJAX客户端生命周期分析(实践篇)

一、引言

在上篇中,我们对微软的ASP.NET AJAX框架的客户端生命周期过程作了理论上的分析。在本篇中,我们要结合一个具体示例针对页面的客户端生命周期期间有关重要事件的发生顺序进行剖析。

二、举例

(一)说明

下面的这个例子展示了在一个有两个嵌套的UpdatePanel控件的页面的客户端事件将被如何引发。请注意点击父面板中的按钮与内嵌的UpdatePanel控件中按钮之间的区别。在父面板中的按钮将引起父面板的更新,而嵌在内部的面板将被删除并重新创建。内嵌面板的按钮点击仅引起内嵌面板的更新。

(二)构建示例网站

启动Visual Studio 2005,选择“文件→新建网站…”,然后选择“ASP.NET AJAX-Enabled Web Site”模板,命名工程为“LifeCycleTest”,并选择C#作为内置支持语言,最后点击OK。

现在,按下图1所示布局修改缺省页面Default.aspx。

图1:示例页面设计时刻快照

在上面页面中,我们把两个服务器控件UpdatePanel进行嵌套。两个UpdatePanel中分别添加一个按钮以便进行事件引发顺序的测试之用。最下面用虚线框框出的是一个HTML <div>面板(名字为‘ClientEvents’),用于展示对于客户端事件引发顺序的追踪输出。下部的‘清除’按钮用于清除<div>面板ClientEvents中的内容。按钮‘整体页面回送’的点击事件对应于Default.aspx.cs文件内的函数FullPostBack_Click,这个函数不执行任何内容,仅用于引发整个页面回送测试之用。点击整个页面右下方的超级链接‘测试页面Unload事件’将导致本页面关闭而整个控制被转移到另一个新的页面(地址为http://www.microsoft.com);此链接用作测试页面的Unload事件之用。

(三)创建客户端JavaScript文件—ClientEventTest.js

在实际开发环境下,客户端页面内的JavaScript代码建议放于单独的.js文件内,既便于代码的统一管理也加强了软件的模块化建设。在本示例中创建这个脚本文件ClientEventTest.js别无它意,正是此目的。因这个文件内容相对较长,所以在此我们仅列出其中前面部分,如下所示:

var app = Sys.Application;

app.add_load(ApplicationLoad);

app.add_init(ApplicationInit);

app.add_disposing(ApplicationDisposing);

app.add_unload(ApplicationUnload);

function ApplicationInit(sender) {

var prm = Sys.WebForms.PageRequestManager.getInstance();

if (!prm.get_isInAsyncPostBack())

{

prm.add_initializeRequest(InitializeRequest);

prm.add_beginRequest(BeginRequest);

prm.add_pageLoading(PageLoading);

prm.add_pageLoaded(PageLoaded);

prm.add_endRequest(EndRequest);

}

$get('ClientEvents').innerHTML = "";

$get('ClientEvents').innerHTML += "APP:: Application init. <br/>";

}

function ApplicationLoad(sender, args) {

$get('ClientEvents').innerHTML += "APP:: Application load. ";

//…………(省略)

代码虽长,但其中的逻辑相对比较简单。一开始,我们建立一个对象Application的实例。然后,我们把此Application对象的load,init,disposing和unload事件分别与特定的事件处理器函数关联起来。于是,在启动示例页面的过程中,将引发这些基本事件,也因而执行这些事件相应的事件处理器函数。

在此,我们以Application对象的init事件的事件处理器ApplicationInit为例。在执行这个事件处理器的过程中,我们又进一步建立了与PageRequestManager对象典型相关联的事件处理器。因为Application对象的init事件只在页面开始生成时创建一次并且在最开始执行,所以,在示例页面启动后,页面最下方的HTML span元素ClientEvents被清空;而其中的第一行显示内容应该被替换为“APP:: Application load.”。

下图2展示了在联机情况下页面初次启动时的屏幕快照。

图2:示例页面初次启动时的屏幕快照

接下来,你可以点击其中的按钮以及链接进行细致的事件引发顺序的追踪分析,在此不再赘述。

三、典型场所下事件发生顺序解析

实际环境下,事件的触发顺序依赖于页面中使用了什么控件以及发生了什么类型的请求(初始化请求,传统回送或是异步回送)。下面,我们来归纳一下几种常见场所下事件的引发顺序。

(一)初始请求阶段引发的事件顺序

在页面的初始请求阶段,仅引发有限的几个客户端事件。假设下面就是初始化请求的情景:

◆Web页面中包含一个ScriptManager控件,且该控件的SupportsPartialRendering和EnablePartialRendering属性都置为true。

◆请求为GET类型;

◆服务器能正常响应。

在这种情况下,将依次发生以下客户端事件:

1、初始化请求发生给服务器;

2、客户端接收到响应;

3、Application实例引发init事件;

4、Application实例引发load事件。

请注意,init事件仅在整个页面生命周期过程中的Application实例化时发生一次,它不会再被后来的异步回送所引发。在初始化请求(注意是请求)期间,再没有任何的PageRequestManager事件引发。

(二)异步回送阶段引发的事件顺序

在一次异步回送中,将有一些页面数据被发送到服务器,接收一个服务器端的响应,然后更新页面的相应部分。我们不妨假定存在如下的一个异步回送的场所:

◆页面中包括一个ScriptManager控件,并且该控件的SupportsPartialRendering和EnablePartialRendering属性都为true;

◆页面中存在一个UpdatePanel控件,并且此控件的ChildrenAsTriggers属性值为true;

◆在UpdatePanel控件内部存在一个用于引发异步回送的按钮;

◆成功地从服务器端获得响应。

那么,上面情况将对应下面的客户端事件发生顺序:

1、点击UpdatePanel控件中的按钮时,引起了一个异步回送;

2、PageRequestManager实例引发initializeRequest事件;

3、PageRequestManager实例引发beginRequest事件;

4、请求被发送到服务器;

5、客户端接收到响应;

6、PageRequestManager实例引发pageLoading事件;

7、PageRequestManager实例引发pageLoaded事件;

8、Application实例引发load事件;

9、PageRequestManager实例引发endRequest事件。

请注意Application的load事件发生在PageRequestManager的pageLoaded事件之后且在endRequest事件之前。

(三)存在多个异步回送时事件引发的顺序问题

当之前的一个请求正在服务器端或浏览器中运行时,用户又发送了一个新的请求时,则发生了多个异步回送。假设下面的场景描述了多个异步回送的情况。

◆页面包括一个ScriptManager控件,并且该控件的SupportsPartialRendering和EnablePartialRendering属性都为true。

◆页面包含一个UpdatePanel控件。

◆在UpdatePanel中有一个引发异步回送的按钮控件被点击两次。第二次的点击发生在服务器端正在处理第一次点击发起的请求。

◆获得了从服务器端返回的对第一次请求的响应。

下面是客户端事件发生的顺序:

1、点击UpdatePanel中的按钮将引发一次异步回送。

2、PageRequestManager实例将引发initializeRequest事件。

3、PageRequestManager实例引发beginRequest事件。

4、请求被发送到服务器。

5、再次点击按钮,引发第二次异步回送。

6、PageRequestManager实例针对第二次按钮点击引发initializeRequest事件。

7、PageRequestManager实例针对第一次按钮引发endRequest事件。

8、PageRequestManager实例针对第二次按钮点击引发beginRequest事件。

9、因第二次点击引发的请求被发送到服务器端。

10、接收到针对第二次点击的响应。

11、PageRequestManager实例引发loading事件。

12、PageRequestManager实例引发pageLoaded事件。

13、Application实例引发load事件。

14、PageRequestManager实例引发endRequest事件。

【注意】默认情况下,异步回送行为一般是最近发生的那次异步回送优先级较高。如果两个异步回送按顺序发生,并且第一个异步回送仍在浏览器处理中,则第一个回送将被取消。如果第一个回送已被发送到了服务器端,则服务器在第二个请求到来并处理它之前是不会返回第一个请求的。

(四)当用户浏览焦点脱离开本页面时引发事件的情况

当用户从本页面转向访问其它页面时,当前的页面会从浏览器中卸载;因此,这时你可以通过控件unload事件来释放有关资源。我们不妨假定当用户转向访问其它页面时存在如下情况:

◆页面中包括一个ScriptManager控件,并且该控件的SupportsPartialRendering和EnablePartialRendering属性都为true。

◆存在将转向的目标页面。

于是,下面对应发生在客户端的事件顺序:

1、初始化一个对新页面的请求;

2、浏览器获得请求新页面的响应;

3、Application实例引发unload事件;

4、显示新页面。

如果在新页面请求时发生了错误,依然会引发unload事件;只是不显示新页面罢了。

四、总结

本文中,我们使用一个具体的例子针对ASP.NETAJAX客户端生命周期中涉及的主要事件引发的顺序给出了追踪分析。但此示例显然有其特殊性且仍嫌粗略,实际开发中宜结合具体问题作针对性分析,以图从根本上掌握ASP.NETAJAX客户端生命周期中引发的主要事件先后顺序及其间的逻辑关系。

 
ajax技术,无刷新技术 导读:ScriptManager控件包括在ASP.NET 2.0 AJAX Extensions中,它用来处理页面上的所有组件以及页面局部更新,生成相关的客户端代理脚本以便能够在JavaScript中访问Web Service,所有需要支持ASP.NET AJAXASP.NET页面上有且只能有一个ScriptManager控件。在ScriptManager控件中我们可以指定需要的脚本库,或者指定通过JS来调用的Web Service,以及调用AuthenticationService和ProfileService,还有页面错误处理等。 ASP.NET AJAX入门系列(3):使用ScriptManagerProxy控件 导读:在ASP.NET AJAX中,由于一个ASPX页面上只能有一个ScriptManager控件,所以在有母版页的情况下,如果需要在Master-Page和Content-Page中需要引入不同的脚本时,这就需要在Content-page中使用ScriptManagerProxy,而不是ScriptManager,ScriptManager 和 ScriptManagerProxy 是两个非常相似的控件。 ASP.NET AJAX入门系列(4):使用UpdatePanel控件(一) 导读:UpdatePanel可以用来创建丰富的局部更新Web应用程序,它是ASP.NET 2.0 AJAX Extensions中很重要的一个控件,其强大之处在于不用编写任何客户端脚本,只要在一个页面上添加几个UpdatePanel控件和一个ScriptManager控件就可以自动实现局部更新。通过本文来学习一下UpdatePanel简单的使用方法(第一)。 ASP.NET AJAX入门系列(5):使用UpdatePanel控件(二) 导读:UpdatePanel可以用来创建丰富的局部更新Web应用程序,它是ASP.NET 2.0 AJAX Extensions中很重要的一个控件,其强大之处在于不用编写任何客户端脚本,只要在一个页面上添加几个UpdatePanel控件和一个ScriptManager控件就可以自动实现局部更新。通过本文来学习一下UpdatePanel其他的一些使用方法(第二)。 ASP.NET AJAX入门系列(6):UpdateProgress控件简单介绍 导读:在ASP.NET AJAX Beta2中,UpdateProgress控件已经从“增值”CTP中移到了ASP.NET AJAX核心中,本文简单介绍一些它的基本用法,翻译自官方文档。 ASP.NET AJAX入门系列(7):使用客户端脚本对UpdateProgress编程 导读:在本文章中,我们将通过编写JavaScript来使用客户端行为扩展UpdateProgress控件,客户端代码将使用ASP.NET AJAX Library中的PageRequestManager,在UpdateProgress控件中,将添加一个Button,来允许用户取消异步更新,并且使用客户端脚本来显示或者隐藏进度信息,翻译自官方文档。 ASP.NET AJAX入门系列(8):自定义异常处理 导读:在UpdatePanel控件异步更新时,如果有错误发生,默认情况下会弹出一个Alert对话框显示出错误信息,这对用户来说是不友好的,本文看一下如何在服务端和客户端脚本中自定义异常处理,翻译自官方文档。 ASP.NET AJAX入门系列(9):在母版页中使用UpdatePanel 导读:本文简单介绍一下在母版页中使用UpdatePanel控件,翻译自官方文档。 ASP.NET AJAX入门系列(10):Timer控件简单使用 导读:本文主要通过一个简单示例,让Web页面在一定的时间间隔内局部刷新,来学习一下ASP.NET AJAX中的服务端Timer控件的简单使用。 ASP.NET AJAX入门系列(11):在多个UpdatePanle中使用Timer控件 导读:本文将使用Timer控件更新两个UpdatePanel控件,Timer控件将放在UpdatePanel控件的外面,并将它配置为UpdatePanel的触发器,翻译自官方文档 作者:TerryLee 出处:http://terrylee.cnblogs.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值