您的位置:首页 > 其它

Atlas 实现机制浅析 [1]

2006-03-17 11:33 429 查看
原文:http://www.blogcn.com/User8/flier_lu/blog/28949768.html

[0] 概述

   上周 MS 发布了面向 ASP.NET 的 AJAX 框架 —— Atlas 最新 CTP 2006.1 预览版, ScottGu 在其 blog 上做了较为详细的介绍。

New Atlas Build Available for Download with ASP.NET 2.0

   更详细的更新说明,可以参考 nikhilk 的一篇 blog

Atlas M1 Refresh - Some More Goodies

   关于 Altas 的概况介绍和简单实例,可以参考 nikhilk 在 PDC05 上的一个讲义和实例

Atlas Presentation Slides and Demos

   详细的介绍和使用方法,可以参考 atlas.asp.net 网站,以及相关的 quickstart 教程,这里就不再罗嗦了。

   有兴趣做试验的朋友,可以下载 ScottGu 以前写的一个例子,后面的很多分析也将在这个例子的基础上进行。

Making a List, Checking it Twice (Cool Ajax Sample App with ASP.NET 2.0 and Atlas)

   与 .NET 和 Java 平台下其它 AJAX 框架相比,Altas 最大的亮点就在于与 ASP.NET 现有机制的无缝融合。通过 VS.NET 集成开发环境,使用者可以在对 js 和 AJAX 不甚了解的情况下,以非常自然的方式使用到最先进的技术。此外直接在 js 一级提供 WebService 的调用支持,也大大降低了对 ws 技术的使用门槛。而 ASP.NET 中一直引以为豪的数据绑定等技术,也可以在 Altas 中无缝得到支持,让现有投资能够最大限度得到保护。从这些意义上来说,虽然 Altas 在 AJAX 理念上没有太多突破,但不失为一个强大且实用的 AJAX 框架,非常符合 MS 在技术运用上的一贯原则。

   Altas 与 .NET 下其它 AJAX 框架的横行比较,可以参考这篇文章

Welcome to my comparison of AJAX frameworks for ASP.NET

[1] 整体结构

   从整体结构上来看,Altas 的核心在于 <atlas:ScriptManager .../> 这个标签,所有支持 Altas 的页面都必须有且只有一个此标签,以引入 Altas 的基础架构支持。在此基础上,通过 <altas:UpdatePanel .../> 标签定义需要异步更新的范围,避免传统 Post Back 模式下的全页面刷新。而需要支持 AJAX 模式获取数据的控件,则可以通过 js 脚本和 xml 脚本两种方式定义,并由 Altas 框架进行动态 patch 以实现标准 web 控件的 AJAX 支持。此外就是 WebService 调用和数据绑定的支持机制,也是利用 Altas 框架的基础架构实现的。

1.1 ScriptManager

   首先,ScriptManager 是一个容器,用户可以在 ScriptManager 标签下定义期望引用的其它 js 库,以及希望通过 js 直接调用的 WebService 服务。
例如在如下的定义中,ScriptManager 控件将保存对两个客户端 js 库和 ComplexService 服务的引用,并在页面 Render 的时候写入适当的支持代码。我们可以通过 ScriptManager.Scripts 和 ScriptManager.Services 属性访问类似定义。
 1<atlas:ScriptManager runat="server" ID="UpdatePanel2" 
 2  EnableScriptComponents="True" EnablePartialRendering="True">
 3  <Scripts>
 4    <atlas:ScriptReference ScriptName="AtlasUIMap" />
 5    <atlas:ScriptReference Path="~/MyScripts/MyScript.js" />
 6  </Scripts>
 7  <Services>
 8    <atlas:ServiceReference Path="ComplexService.asmx" />
 9  </Services>
10</atlas:ScriptManager>
   其中 ScriptReference 非常简单,支持通过 ScriptName 或 Path 属性指定脚本。
   ScriptName 指定 Altas 内建的库名称,在 FrameworkScript 类型中有具体定义。这个属性在有的文档和例子中,也直接称为 Name 属性,但最新的 Altas M1 中已改为 ScriptName。这个脚本类型将被通过 ScriptManager.ConvertFrameworkScriptToFileName 函数转换为对应的 js 文件名。
1public enum FrameworkScript
2<script src="ScriptLibrary/Atlas/Debug/Atlas.js" type="text/javascript"></script>
 2
 3<script type="text/xml-script">
 4<page xmlns:script="http://schemas.microsoft.com/xml-script/2005">
 5  <references>
 6    <add src="ScriptLibrary/Atlas/Debug/AtlasUIMap.js" />
 7    <add src="MyScripts/MyScript.js" />
 8    <add src="ComplexService.asmx/js" />
 9  </references>
10  
11</page>
12</script>  
   值得注意的是,Altas 会自动根据 web.config 中 system.web/compilation 的配置,选择 Debug 或 Release 模式的脚本。Release 模式脚本删去了多余的空格等修饰负荷,少了一些调试方面的支持。如果希望对 Altas 的脚本直接进行修改,别忘了两个版本的代码进行同步。

   此外,ScriptManager 是一个协调者,它自身维护了一些常用的状态,并会根据状态来切换 Altas 引擎的工作机制。
   最常使用的是 EnablePartialRendering 和 EnableScriptComponents 属性。

   EnablePartialRendering 属性决定是否启用局部重绘的模式。
   传统的 Post Back 模式页面,在用户 submit 时会重绘整个页面,并导致浏览器显式的闪烁。而在基于 AJAX 技术的 Altas 框架中,可以通过 UpdatePanel 标签指定需要重绘的局部。这样一来页面在处理请求时,会首先根据 ScriptManager.IsInPartialRenderingMode 属性判断是否在重绘模式中。如果在重绘模式,则仅仅将需要重绘的 UpdatePanel 内容,返回给客户端浏览器,并由 Altas 自动进行内容的更新。通过这种模式,使用者可以在对代码几乎无需修改的情况下,直接享受到 AJAX 带来的客户端用户体验的提升。

   EnableScriptComponents 属性决定是否启用 XML 脚本模式。
   XML 脚本模式是 Altas 引入的基于 XML 的描述性组件定义模型,可以通过一组 XML 标签,定义页面中已有 Web 组件的 AJAX 行为,而无需对现有组件进行修改和调整。而且因为所有的行为都是由 Altas 引擎在客户端动态绑定,所以组件的目标也可不仅仅限于现有的 Web 组件。具体的介绍可以参考 Atlas XML Script。而对于某些特殊情况,例如 ASP.NET 2.0 中的 master 页面,可以通过此属性关闭 XML 脚本支持,以大幅度简化页面的功能,此时 Altas 会自动使用 AtlasRuntime.js (57K) 替换完整的 Atlas.js (174K) 脚本。

   最后,在了解了 ScriptManager 的基本职责后,我们来看看它的实现。
1public interface IScriptControlContainer
2
6
   ScriptManager 是一个 Web 界面控件,可以直接在 VS.NET 的设计界面中进行调整;它实现了 IScriptControlContainer 接口以作为 IScriptControl 的容器,对注册到容器的不支持 IScriptControl 接口的类型,将自动建立 GenericScriptControl 进行包装;实现 IPostBackDataHandler 接口则是用于在 Post Back 时处理局部重绘的支持。

   在重载的 Control.OnInit 方法中,将根据页面请求头中 delta 属性是否为 true 来判断,当前控件是否处于局部重绘中。如果是局部重绘模式,则关闭页面的 trace 模式,并接管页面 LoadComplete 事件,并最终根据每个 UpdatePanel 的重绘状态,返回实际的重绘结果。此外无论是否局部重绘,都会接管页面的 PreRenderComplete 事件,以便完成前面提到的 Altas.js 和 XML 脚本的输出。伪代码如下:
 1protected override void OnInit(EventArgs e)
 2protected override void OnPreRender(EventArgs e)
 2private void OnPagePreRenderComplete(object sender, EventArgs e)
 2{
 3    // 是否在局部重绘模式中
 4    if (_inPartialRenderingMode)
 5    {  
 6        // 接管 Page 的 Render 方法
 7    Page.SetRenderMethodDelegate(new RenderMethod(RenderPageCallback));
 8    return;
 9  }
10
11    // 获取客户端浏览器类型
12    string browser = _page.Request.Browser.Browser;
13
14    if (browser == "IE")
15        RegisterFrameworkScript("AtlasCompat.js");
16    else if(browser == "AppleMAC-Safari")
17        RegisterFrameworkScript("AtlasCompat2.js");
18
19    // 是否启用 XML 脚本模式
20    if (_effectiveEnableScriptComponents)
21        RegisterFrameworkScript("Atlas.js");
22    else
23        RegisterFrameworkScript("AtlasRuntime.js");
24
25    if (存在任意一种脚本服务、控件或引用)
26    {
27        StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);
28        
29        // 输出 XML 脚本
30    writer.Write("<script type=\"text/xml-script\">");
31    RenderXmlScript(writer);
32    writer.Write("</script>");
33    
34        // 是否需要输出初始化脚本
35        string proxyScript = GetClientProxyScript();
36        
37        if (proxyScript != null || _enablePartialRendering)
38        {
39            writer.Write("<script type=\"text/javascript\">");
40            
41            // 输出客户端代理脚本
42            if (proxyScript != null)
43                writer.Write(proxyScript);
44                
45            // 输出局部重绘模式初始化脚本
46            writer.WriteLine("Web.WebForms._PageRequest._setupAsyncPostBacks(document.getElementById('" + _page.Form.ClientID + "'), '" + UniqueID + "');");
47
48            writer.Write("</script>");
49        }
50
51        // 将上述脚本注册到页面的客户端脚本管理器
52        _page.ClientScript.RegisterStartupScript(typeof(ScriptManager), "ScriptManager", writer.ToString(), false);          
53    }
54}
   至此,我们对 Altas 的核心组件 ScriptManager 的大致结构已经有了初步的了解,接下来会针对基于 UpdatePanel 的局部重绘模式、基于 XML 脚本的声明式定义、基于 XMLHTTP 的后台数据通讯机制、以及 WebService 和 DataBinding 支持的实现机制进行分析。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: