了解 ASP.NET AJAX UpdatePanel 触发器——ASP.NET AJAX学习笔记“出自msdn”

 

简介

Microsoft的 ASP.NET 技术提供了一个面向对象、事件驱动的编程模型,并将其与已编译代码的优势结合起来。但其服务器侧的处理模型仍存在技术本身所固有的几点不足,其中很多可以通过Microsoft ASP.NET 3.5 AJAX Extensions的新特性得到解决。这些扩展提供了大量新的客户端特性,包括进行页面局部呈现而无需刷新整个页面、通过客户端脚本(包括ASP.NET 配置文件 API)访问 Web 服务、以及功能广泛的客户端侧API,用于映射 ASP.NET 服务器侧控件集中的许多控件方案。

本白皮书将深入介绍 ASP.NET AJAX UpdatePanel 组件的 XML 触发器功能。通过 XML 触发器,可以精确控制能提供特定UpdatePanel 控件的局部显示功能的组件。

本白皮书基于 .NET Framework 3.5的Beta 2 版本及Visual Studio 2008。之前作为ASP.NET 2.0 插件程序集的ASP.NET AJAX Extensions现在被集成到 .NET Framework基础类库中。本白皮书还假定读者使用的是Visual Studio 2008 而非 Visual Web Developer Express,并将根据Visual Studio 的用户界面提供演练(但无论使用的是哪个开发环境,代码列表都将是完全兼容的)。

触发器

默认情况下,某个给定 UpdatePanel 的触发器自动包含了调用回传的所有子控件,包括(例如)AutoPostBack属性被设为 true 的TextBox 控件。但也可通过使用标记声明性地包含触发器。这一操作在UpdatePanel 控件声明的 <triggers> 部分完成。尽管可以通过Triggers 集合属性访问触发器,但建议在运行时(例如,如果某个控件在设计时不可用)注册局部显示触发器:在Page_Load 事件中,使用您页面中 ScriptManager 对象的 RegisterAsyncPostBackControl(Control)方法。请记住页面是无状态的,因此每次创建控件时都要重新注册这些控件。

通过将 ChildrenAsTriggers属性设为 false,可以关闭自动包含子触发器的功能(这样创建回传的子控件就不会自动触发局部呈现)。这允许在指定可调用页面呈现的控件时享有最大的灵活性,所以建议采用这种方法。这样,开发者将以“决定参与”的方式来响应事件,而不是处理可能发生的任何事件。

注意,当 UpdatePanel 控件被嵌套时,若将 UpdateMode 设为 Conditional,那么当子 UpdatePanel 被触发但父 UpdatePanel 未被触发时,则只有前者被刷新。但如果父UpdatePanel 也被刷新,则导致子 UpdatePanel 也将被刷新。

<Triggers>元素

使用 Visual Studio 中的标记编辑器时,你可能(从 IntelliSense)注意到一个 UpdatePanel 控件有两个子元素。最常见的元素是<ContentTemplate> 元素,它实质上封装的是将被update panel 包含的内容(即我们实现局部呈现的内容)。另一个元素是<Triggers>,用于指定页面上的控件(或您在使用的用户控件),该控件将触发<Triggers> 元素所属 UpdatePanel 的局部呈现。

<Triggers>元素可以包含以下两个字节点中的每一个且数量不限:<asp:AsyncPostBackTrigger><asp:PostBackTrigger>。这两个子节点都接受两个属性:ControlIDEventName,且可以在当前封装单元中指定任何控件(例如,如果您的UpdatePanel 控件位于一个 Web 用户控件中,您不应试图引用将放置用户控件的页面上的控件)。

<asp:AsyncPostBackTrigger>元素最大的用处是它可用于从封装单元中的 任何 UpdatePanel 控件的子控件指定事件,而不只是此触发器的父UpdatePanel。这样,任何控件都可触发局部页面更新。

同样,<asp:PostBackTrigger>元素可用于触发局部页面呈现,但要求到服务器的完整往返行程。此触发器元素也可用于在控件如无异常则正常触发局部页面呈现时(例如,当UpdatePanel 控件的 <ContentTemplate> 元素中有一个 Button 控件时),强制执行完整页面呈现。同样,PostBackTrigger 元素可指定当前封装单元中的任何UpdatePanel 控件的任何子控件。

<Triggers>元素引用

标记子项:

标签

说明

<asp:AsyncPostBackTrigger>

指定一个控件和事件,将引发包含触发器引用的UpdatePanel的局部页面更新。

<asp:PostBackTrigger>

指定一个将引发完全页面更新(整个页面刷新)的控件和事件。此标记可用于在控件如无异常则正常触发局部页面呈现时强制执行完整页面呈现。

演练:Cross-UpdatePanel触发器

  1. 新建一个 ASP.NET 页面,并建立一个 ScriptManager 对象集来启用局部呈现。向新建页面添加两个UpdatePanel:首先添加一个 Label 控件(Label1),然后添加两个 Button 控件(Button1 和 Button2)。Button1 的文字为 “Click to Update Both”,Button2 为 “Click to Update This”或类似内容。在第二个 UpdatePanel 中只添加一个 Label 控件(Label2),但将其 ForeColor 属性设为默认值以外的值以便区别。
  2. 将两个 UpdatePanel 标记的 UpdateMode 属性都设为 Conditional

程序列表 1:default.aspx的标记:

 

 

 

  1. 在 Button1 的 Click event handler中,将 Label1.Text 和 Label2.Text 设为与时间无关的值(如 DateTime.Now.ToLongTimeString())。在 Button2 的 Click event handler 中,只将 Label1.Text 设为与时间无关的值。

程序列表2:default.aspx.cs中的代码文件(已处理)

 

 

 

  1. 按 F5 键运行项目。注意,当您单击 Update Both Panels时,两个标签的文字都改变了。但单击Update This Panel 时,只有 Label1 更新。

 

 

 

内幕与解密

利用我们前面刚建的示例,可以了解 ASP.NET AJAX 的作用以及 UpdatePanel 跨层面的触发器是如何运作的。为此,我们将使用生成页面的源HTML,以及被称作 FireBug 的 Mozilla Firefox 扩展,它将帮助我们更方便地查看AJAX 回传。此外我们还将使用Lutz Roeder 的 .NET Reflector 。上述工具都可从网上免费下载,通过Internet 搜索即可找到。

通过对页面源代码的检查发现几乎没有什么异常。UpdatePanel 控件呈现为 <div> 容器,而且我们可以看到<asp:ScriptManager>提供的脚本源。此外在 AJAX 客户端脚本库内部,还有一些新的AJAX 特有的对 PageRequestManager 的调用。最后我们看到两个UpdatePanel容器。其中一个有呈现的<input>按钮以及两个呈现为<span>容器的 <asp:Label>控件。(如果您在FireBug 查看 DOM 树,可以发现标签变暗,表示它们不产生可见内容。)

单击 Update This Panel按钮,注意顶部的UpdatePanel 将被更新为当前的服务器时间。在FireBug 中选择 Console 选项卡以便查看请求。首先查看POST 请求参数:

 

 

 

 

注意,UpdatePanel 向服务器侧 AJAX 代码准确表示了通过 ScriptManager1参数触发的是哪个控件:即UpdatePanel1控件的Button1。现在单击 Update Both Panels按钮。然后查看响应。我们将看到一个由一系列竖线分隔的变量集组成的字符串。其中将看到顶部的UpdatePanel 即 UpdatePanel1 的所有 HTML 都发送至浏览器。AJAX 客户端脚本库通过 .innerHTML 属性,用新内容代替了 UpdatePanel 的原有 HTML 内容,因此服务器将更改的内容作为HTML 发送出去。

现在单击 Update Both Panels按钮并查看从服务器发回的结果。结果很相似:两个 UpdatePanel 都接收到了来自服务器的新HTML。与前一个调用一样,发送了其它的页面状态。

正如我们能看到的那样,由于没有使用专门的代码来执行 AJAX 回传,AJAX 客户端脚本库不需任何额外的代码就可以截取表单回传。服务器控件自动使用JavaScript 以便无需自动提交表单:ASP.NET 已经自动注入代码以便完成表单验证和状态设定,主要由自动脚本资源包含、PostBackOptions 类和 ClientScriptManager 类来完成。

例如,考虑针对一个 CheckBox 控件进行此操作。检查 .NET Reflector中的类反汇编程序。操作方式为:确保您的System.Web 程序集是打开的,导航到System.Web.UI.WebControls.CheckBox类,打开 RenderInputTag 方法。查找一个检查AutoPostBack属性的条件:

 

 

当某个 heckBox控件上开启了自动回传(通过将 AutoPostBack 属性设为 true实现)时,呈现结果的 <input>标记时,其 onclick属性中便会有一个 ASP.NET 事件处理脚本。然后,对提交表单的截取便可允许向页面注入ASP.NET AJAX 而不产生任何影响。这有助于防止由于可能插入的不准确字符串而造成的打破兼容性的更改。此外,这样还可使 任何定制ASP.NET 控件都可利用 ASP.NET AJAX 的功能,而无需添加代码以支持在UpdatePanel 容器中使用 ASP.NET AJAX。

<triggers>功能对应于在 PageRequestManager对 _updateControls的调用中初始化的值(注意 ASP.NET AJAX 客户端脚本库利用了“以下划线开始的方法、事件和字段名称都标记为内部的,且不能单独在库之外使用”这一约定)通过这一功能,可以查看哪些控件用于引发AJAX 回传。

例如,我们向页面添加两个额外的控件,将其中一个控件完全放在UpdatePanel 之外,另一个放在UpdatePanel 之内。我们将在上面的 UpdatePanel 内添加一个 CheckBox 控件,并添加一个定义了多种颜色的DropDownList。新的标记如下:

程序列表 3:新标记

 

 

代码文件如下:

程序列表 4:代码文件

 

 




 

 

 

 

 

从上面的屏幕截图中可以清楚地看出,最后单击的按钮是右面的Update This Panel,它更新了上方的时间,而不受底部时间的影响。通过单击还关闭了日期显示,因为只有下方有日期显示。最后一个有意思的地方是底部标签的颜色:它的更新时间比标签文本还要晚,这表示控件状态相当重要,用户希望通过AJAX 回传将其保留。然而,时间未被更新控件在服务器上重新显示时,时间通过保存由ASP.NET 运行时解释的页面的 __VIEWSTATE 字段自动重新填充。ASP.NET AJAX 服务器代码无法识别控件在哪些方法中更改状态,它只是从视图状态重新填充,然后运行适当的事件。

但应指出,如果我们之前在 Page_Load 事件中初始化了时间,那么时间就会正确显示了。因此,开发者应注意在适当的event handler 中运行适当的代码,并避免在适合使用控件event handler 时使用Page_Load。

小结

ASP.NET AJAX Extensions UpdatePanel 控件有多种用途,可以使用大量方法来识别导致其更新的控件事件。它支持通过自己的子控件自动更新,也可以响应页面上其它位置的控件事件。

要降低可能的服务器处理负载,建议将 UpdatePanel 的 ChildrenAsTriggers属性赋值为 false,且将事件设为“选择参与”而非默认包含。这也可以防止不需要的事件可能引发的不必要的结果,包括验证和对输入字段的更改等。这些类型的bug 可能很难隔离,因为页面更新对于用户而言是透明的,因此其引发原因就可能不是立即可见的。

通过检查 ASP.NET AJAX 表单张贴截取模型的内部运行,我们可以确定它使用了ASP.NET 早已提供的框架,以便于保持对使用同一个框架设计的控件的最大兼容性,并尽量减少为页面额外编写的JavaScript。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值