领先技术

ASP.NET AJAX 4.0 中的数据绑定

Dino Esposito

下载示例代码

围绕该 bush 击退停止:AJAX 是可能仅使用一个强的 JavaScript 引擎,可以在客户端浏览器中运行,并提供更高级和异步功能基础的。 JavaScript 库当前包含在 ASP.NET 3.5 SP 1 尝试是一个需要,但不足,将这样的库。 一个功能更强大的 ASP.NET AJAX 平台是必需的的并且它只是被引入了 ASP.NET AJAX 4.0 的一部分。

abstractly 说的 AJAX 基于前端是表示层与某些应用程序逻辑的实现组合丰富的 UI 功能。 应用程序逻辑是实质上是后面所有用例关系图中设计和分析阶段的代码。 应用程序逻辑表示应用程序和如何在用户希望与整个系统进行交互预期的的行为。

什么是 AJAX 前端在相当唯一至少与一个典型的网站或智能客户端前端,进行比较时是按需要与低级别编程的工具中混合使用丰富的用户体验的元素。 一个 AJAX 前端运行在客户端浏览器中,因为它可以依赖于只生成用户界面的 HTML 和仅以使特殊效果、 拖放、 异步的数据提取和部分更新视觉元素组成的 JavaScript。

若要满足期望,一个现代的和有效的 AJAX 平台必须提供两个重要的功能。 第一次,它必须启用开发人员将异步调用一个 HTTP 表面的特殊服务器模块。 第二个,它必须启用开发人员将其任何收到的原始数据合并到现有页文档对象模型 (DOM)。 这两个的功能但,将丢失其固有的吸引力的很多如果不是的简单而有效的方式实现。

在 ASP.NET 3.5 Service Pack 1 中开发人员发现一个功能强大且可靠的 API 以异步方式连接到基于 HTTP 的 Web 服务的图层。 ASP.NET AJAX 3.5 使得可能,简便总体,您可以从客户端页中引用 Web 服务。 这样做,框架也会自动生成镜像服务约定的 JavaScript 代理类。 现有的 AJAX 框架,同时在服务器和客户端,工作将使开发人员的数据序列化的所有详细信息。 从 JavaScript 开发人员的角度来看,就像通过方法公开行为本地 JavaScript 对象是一个远程 Web 服务 (仍受已知的相同源策略)。

ASP.NET 3.5 1 不能提供相同的优点就是而言生成用户界面。 它使其有很容易地从服务器,获取原始数据,但它不会提供一个功能强大的界面,在用户界面中显示此原始的数据的方式在很多。 AJAX 支持 ASP.NET 3.5 SP 1 中的该主要弱点是缺乏有效的工具为客户端的数据绑定和 HTML 模板。 这是为客户端模板呈现的引擎和一个 made-to-measure 数据绑定语法是您在 ASP.NET AJAX 4.0 中找到最引人注目的功能的原因。

本文,我将为支持 ASP.NET AJAX 4.0 中查看在现实世界 AJAX 开发的支柱。 这样,我将主要精力集中在客户端模板和数据绑定,但不会忽略其他好吃,如 ADO.NET 数据服务代理类和编程功能。

pillars 的现实世界 AJAX 开发

现实世界 AJAX 开发是关于通过 Web,构建丰富的用户界面,它需要新的设计模式的应用程序和雇用新编程的工具的。

较长的时间的任何 Web 用户界面表示整个步骤方面的可用性和响应,如果与任何桌面的用户界面向后。 时间长 Web 开发人员只需忽略 (因为它不与他们的工作) 数量 UI 模式和编程功能,包括预测提取、 缓存、 监视远程任务、 显示上下文相关和向下钻取、 subviews、 部分用户界面禁用,和模式。

在传统 Web 开发,生成用户界面的已完全委派给服务器端,并且有效的实现使用服务器端数据绑定和特殊的控件。 在 AJAX 模式的出现做此模式已过时 unappealing 来提高应用程序的数字。

数据绑定,但,是太强大一个功能,忽略的 AJAX 编程模型中。 此外,面向对象的很难拒绝时超出给定阈值的代码的复杂性。 一次 Web 应用程序保持相当唯一小痕迹、 缓存下载和丰富的功能的组合。

实际的 AJAX 开发途中 JavaScript 库是仅承受方法添加编程功能。 通过 JavaScript 库,您提供对象的方向不 OOP 语言 ; 的基础您提供丰富而现成 UI 小组件 ;您可以提供有效代码数据绑定完全在客户端的端编程的工具。

功能强大的客户端的数据绑定模型,您不能没有实际的 AJAX 开发一个功能强大平台。

要求客户端的数据绑定

有两种基本的模式实现数据绑定功能。 一个是在 HTML 消息模式,在其他浏览器端模板模式。 前者,则需要进行远程服务调用返回 prearranged 的 HTML 标记的组件以供显示。 后者是所有有关设置下载原始数据,并在客户端上确定如何呈现它的机器。

HTML 消息模式与智能的部分呈现,在于它不涉及任何视图状态,并且可以被配置成不绑定到同一个应用程序中发生的任何其他回发的操作的自治操作窗体类似。 HTML 消息模式的实现中的所有内容上发生服务器 ;任何数据绑定是实质上是涉及如 DataGrid 和 ListView 和提取数据的托管的容器的控件绑定的典型服务器端数据的窗体。

使用 ASP.NET 3.5 中可用的工具,可以轻松地实现 HTML 消息模式。 所有需要在客户端上的绑定返回标记到页面 DOM。 以下代码段显示了确实要求从编码的角度来看:

grid.innerHTML = markup;

在示例中,网格指示 HTML 元素包含在标记 — 通常这是一个 DIV 标记。 变量名为标记,另一方面,指示 HTML 作为响应服务方法调用中获得的任何文本块。

毫无疑问用于实现 HTML 消息模式,服务必须合并逻辑以检索或计算数据以返回,和设置为 HTML 数据的格式所需的任何逻辑。

一般情况下,一个基于 HTML 消息模式的解决方案需要更多的带宽,随着每个远程方法调用响应的平均大小的增加。

浏览器端模板 (BST) 模式需要您侧的多个编码,但也可以提供更好的结果,同时方面的灵活性和带宽优化。 BST 模式基于想法,您将放远程调用来检索数据。 在客户端允许操作与 JavaScript 的格式,然后被下载数据。 最后,数据与现有页面 DOM 合并,并会产生任何复杂的界面,您需要。

频率过高,AJAX 模式的功能是错误地表示的异步更新小部分用户界面的可能性。 它是一件事异步获取标量值 (例如,银行帐户的当前余额) 和页面 DOM ; 到现有的插入它是相当另一个操作异步刷新经常更改,并且需要一个 gridlike 基础结构,以显示数据数组。

服务器端是服务器控件,作为下面简单:

Collection<StockInfo> stocks = GetLatestQuotes(...);
DataGrid1.DataSource = stocks;
DataGrid1.DataBind();

是多少? 这样在客户端的等效项 第一部分都可以轻松地映射到 ASP.NET 3.5 的功能。 您做的全部操作是实例化和客户端代理服务器用于远程服务能够获得最新的值,就像这样:

var service = new Samples.Services.FinanceService();
var stocks = service.GetLatestQuotes(...);

股票变量是一个 JavaScript 数组对象代表您收到的数据。 您如何将调整此块的原始数据到现有的 HTML 布局? BST 模式是这里帮助。 它要求您定义以下元素:您自己的语法 HTML 模板和相关的数据的占位符 ;实际的数据绑定到占位符 ; 您自己的语法获取模板和数据并生成一个 HTML 工厂更新标记 ;并将粘附到占用它一起同时提供一个易于管理的编程接口的代码。

ASP.NET AJAX 4.0 提供现成的 BST 模式的实现。 在 MicrosoftAjaxTemplates.js 文件中定义的 ASP.NET AJAX 模板在基本框架。 您需要引用 ScriptManager 控件 (或 ScriptManagerProxy) 通过此文件,如果您使用的母版页。 如果您使用 ASP.NET MVC 或不希望通过传统 < 脚本 > 脚本文件的引用标记,则还必须添加对 MicrosoftAjax.js 初步的引用。

HTML 模板语法

多年的 ASP.NET 编程已证明超出任何合理的疑问的 HTML 模板是从数据创建 Web 用户界面的极好的方法。 一个 HTML 模板是一个包含文本、 ASP.NET 控件和占位符绑定数据的 HTML。 绑定到原始数据,并且一个特殊的引擎处理的一个 HTML 模板 morphs 纯 HTML 浏览器呈现到中。 模板存在将数据绑定和生成块的显示 ; 标记绑定之前模板是从视图中隐藏的。

不论相对简单说明,一个 HTML 模板,则很难实现一个现实世界的 AJAX 框架中。 一些尝试做常用库,(如原型 JS,formalize 一个 HTML 模板。 同时还有一个应期望的 HTML 模板从功能上的公用协议,尚不存在一种用于定义在浏览器中的一个 HTML 模板的通用模式。

模板必须能够呈现符合 XHTML 的标记。 模板由基础呈现引擎必须尽可能快地处理和应该让引擎之前的延迟的响应的应用程序的用户实现呈现的标记大百分比。 模板必须支持一个非常简单的语法易于读取,时不限于简单的情况的绑定。 您应该能混合使用标记和在模板中的代码。 理想情况下,触发的模板呈现的代码应声明性不特别的干扰。

让我们查看 HTML 模板模型支持 ASP.NET AJAX 4.0 的特征。

ASP.NET AJAX 4.0,一个 HTML 模板是一个 DIV 标记或其他容器标记,与系统的模板类属性,修饰,如下所示:

<div>
<ul id="MyItem" class="sys-template">
       <li>
         {{ Symbol }}, {{ Quote }}, {{ Change }}
       </li>
</ul>
</div>

系统模板的 CSS 类是约定标记元素和最初不可见的内容。 请注意该系统的模板必须定义显式在该母版页的网页或在每个页中中,,如下所示:

<style type="text/css">
.sys-template { display:none; visibility:hidden; }
</style>

模板呈现时, 给出数据上下文,该模板的正文可以绑定到公共字段和数据上下文对象的属性。 同样,在模板中的任何元素都可以引用字符串计算出的任何 JavaScript 表达式。

数据绑定语法

表示在模板中的占位符之间外部数据绑定语法的是,如下所示:

{{ expression }}

所述,表达式可以是公共成员的数据上下文对象或 JavaScript 表达式返回一个字符串,字符串的名称。 这样的表达式可以出现在模板中的任意位置并还可将一个值赋给属性,如下所示:

<div>
  <ul id="MyItem" class="sys-template">
     <li>
       <asp:Label runat="server"
            Text="{{CompanyName}}" />
     </li>
  </ul>
</div>

进行的普通 HTML 文本 ; 没有一个 HTML 模板您可以使用以及 ASP.NET 标记。 给出上述代码段,如下标记发出 Label 控件:

<span>{{ CompanyName }}</span>

正如您所看到的服务器控件在页的源代码中使用不会影响客户端呈现的模板。

使用熟悉的 onXXX 语法模板内,或通过 $ addHandler 函数在 Microsoft AJAX 库中,可以定义客户端事件。

DataView 控件和模板实例化

若要显示的数据,模板必须被实例化,绑定到数据和呈现在容器中。 Sys.UI.DataView 客户端控件可用于自动执行任务和简化所有这些任务。

DataView 控件是实质上是一个组件,将某些输入数据和 ASP.NET AJAX 模板,并生成 HTML 标记将显示在页中。 在 DataView 还引用作为行为的组件。 一般情况下,行为是基于脚本的组件,一次附加到的一个 DOM 元素更改 HTML 元素在客户端浏览器中的工作的方式。 您可以使用两种方法之一中的一个行为。 既可以以声明方式将行为附加到它的目标 DOM 元素或您可以创建行为的实例,并以编程方式将其配置。 在后一种情况下行为和模板之间的关联就是配置的一部分。 让我们先解决声明性的方法。

我任何进一步之前,但,我阐明在 DataView 是一个可能的行为的组件。 任何您阅读在以后有关声明的实例化,并且附件适用于在可能运行在 ASP.NET AJAX 的任何行为。


图 1 的操作中的 DataView 行为

以声明方式将附加行为

若要将行为附加到 DOM 元素,使用该系统: 附加自定义属性。 正如您所见,属性是与命名空间 URI,它使得 XHTML 兼容。 您声明 < 正文 > 中的 sys 前缀元素:

<body xmlns:sys="javascript:Sys" ...>

sys 前缀映射到 javascript:Sys 命名空间 URI 定义 Microsoft AJAX 库中。 使用该系统: 附加属性充当只有建立一个现有的行为和 HTML 元素之间的关联的用途。 您仍需要实例化行为组件。 可以完成该操作 < 正文 > 中定义另一个自定义 namespaced 属性元素。 该属性的值将引用 JavaScript 对象实例化:

<body xmlns:sys="javascript:Sys"
      xmlns:dataview="javascript:Sys.UI.DataView" ...>

该属性的名称 — — 数据视图,在前面的代码段 — — 是任意的并且可以将其他您喜欢的任何更改。 任何名称,选取,但是,它必须维护的代码以引用行为的其余部分。

任何附加的脚本行为的有效实例化在加载页并获取处理 DOM 元素时发生。 正在加载页的浏览器可能不知道任何有关如何处理这些库定义的行为。 ASP.NET AJAX 框架负责最终它自己的行为的实例化。 但是,ASP.NET AJAX 框架需要特别说明从您继续。 要在启动过程 DOM 分析过程中并在任何系统的任何已分析元素的内容中查找框架特别,: 附加属性。

图 2 控制一个 DataView 对象以编程方式

<script type="text/javascript">

// Define a global instance of the DataView
var theDataView = null;

// This function can be called from anywhere in the page to
// fill the template with passed data and update the page.
function renderTemplate(dataSource) 
{
    // Ensure we have just one copy of the DataView.
    // The DataView's constructor gets a DOM reference to the template.
    if (theDataView === null)
        theDataView = new Sys.UI.DataView($get("MyTemplate"));

    // Bind data to the template associated with the DataView
    theDataView.set_data(dataSource);

    // Force the template to render 
    theDataView.refresh();
}

</script>

由于性能原因而 ASP.NET AJAX 框架不是自动处理的任何方式以及遇到的浏览器的 DOM 元素。 因此,是最多以显式表示的 DOM 元素需要扫描的附加支持声明性的实例化的行为。 可以通过在系统中包含以声明方式实例化的行为 DOM 元素: 激活属性。 使用 < 正文 > 中的属性元素并将其设置的元素 ID 以逗号分隔的列表:

<body xmlns:sys="javascript:Sys"
      xmlns:dataview="javascript:Sys.UI.DataView"
      sys:activate="customerList">

前面的代码指示框架自动实例化任何可能被附加到 customerList DOM 元素的行为。

如果您想激活整个文档,您还可以使用通配符 (*)。 使用此选项尤其是在较大的页面上的谨慎,因为它可能会引入一个呈现的延迟。 完全配置 < 正文 > 中 DataView 行为元素,所有仍保持为是绑定到模板的新数据:

<div id="customerList">
    <ul class="sys-template"
        sys:attach="dataview"
        dataview:data="{{ theCustomers }}">
        <li>
            <span ><b>{{ ID }}</b></span>
            <asp:label runat="server"
                 Text="{{ CompanyName }}"></asp:label>
        </li>
    </ul>
</div>

DataView 组件的丰富编程界面,除了其他的事项包括一个数据属性。 数据属性表示数据绑定模板的上下文。 您可以在以编程方式和以声明方式设置数据属性。 在下面的代码段中,数据属性以声明方式设置为命名 theCustomers 成为全局数组的内容:

<ul class="sys-template"
    sys:attach="dataview"
    dataview:data="{{ theCustomers }}">
...
</ul>

一般情况下,您可以设置数据属性给任何 JavaScript 表达式计算结果为一个可绑定的对象或对象的数组。 您选择的声明性方法,当您希望将某些全局数据绑定模板。

在标题为 A 示例页面使用声明绑定的代码下载示例显示了示例页的完整列表。 图 1 显示了运行中的示例页面。

用于以编程方式绑定,您需要获取一个引用到 DataView 对象并调用的数据属性 setter 方法。 检索该 DataView $ 通过实例查找 Microsoft AJAX 库中定义的帮助器。 DataView 组件的 ID 匹配其附加到 DOM 元素的 ID。 请考虑以下代码段:

<ul class="sys-template"
    sys:attach="dataview"
    id="DataView1">
...
</ul>
<input type="button"
       value="Perform binding"
       onclick="bind()" />

您可以执行数据绑定,仅当用户显式单击按钮时。 此处是您需要将放入绑定 JavaScript 函数的代码:

<script type="text/javascript">
    function bind() {
        theDataView = $find("DataView1");
        theDataView.set_data(theCustomers);
    }
</script>

您第一次检索 DataView 实例 ID,然后将新内容分配给其数据的属性。

母版页的提示

当您使用母版页的网页时,通常将 < 正文 >页面模板在母版中的标记。 然后,需要您编辑母版页将任何所需的行为。 或者,可以放入 < 正文 >在内容占位符的标记,并强制开发人员可以在任何内容页中显式设置该。

< 正文 >标记是需要注册 DataView,如的附加行为并使识别并实例化行为,通过该系统的 DOM 元素: 激活属性。

应该注意的另一种方法存在编辑 < 正文 >标记。 可以使用新的 ClientElementsToActivate 属性上该 ScriptManager 控件,如下所示:

<asp:ScriptManager runat="server"
                   ID="ScriptManagerProxy1"
                   ClientElementsToActivate="*">
    <Scripts>
        <asp:ScriptReference Name="MicrosoftAjaxTemplates.js" />           
    </Scripts>
    ...
</asp:ScriptManager>

请注意只有几个 ScriptManager 控件上定义属性镜像 ScriptManagerProxy 控件是您使用复制 ScriptManager 功能在内容页中包装控件上。 在 ASP.NET 4.0,但是,在 ClientElementsToActivate 是几个属性可以访问这两个控件之间。

您可能想知道 ClientElementsToActivate 像一个字符串数组属性如何影响行为的一个 JavaScript 框架如 ASP.NET AJAX 框架。 当在 ClientElementsToActivate 属性设置时,脚本管理器控件发出额外脚本将一个或多个项添加到 Microsoft AJAX 库中 Sys.Application 对象上的内部数组在页中的行。

以编程方式使用 DataView 控件

到目前为止,我们已检查的方案的 HTML 模板附加到一个 DataView 行为混合在一起布局和数据到新的 HTML。 这不是唯一可能客户端的数据绑定方法。

也可以以编程方式创建 DataView 组件的一个实例,并传递给它作为参数使用的模板。 图 2 提供简要说明,但列表。

在 DataView 的构造函数内部使用该模板对 DOM 的引用。 数据属性的设置方法获取要绑定的新数据。 最后,刷新方法强制显示刚绑定的数据的 HTML 模板的更新。

若要创建的 DataView 实例,您可以还借助于 $ 创建帮助器方法,如下所示:

<script type="text/javascript">
function pageLoad() {
$create(
       Sys.UI.DataView,
       {},
       {},
       {},
       $get("MyTemplate")
);
}
</script>

一种非常常见的情况中使用一个 DataView 明确平滑处理您的编程工作是填充一个复杂的 HTML 模板的数据,从而远程 Web 服务提供。 让我们调查进一步这一点。

从 Web 服务提取数据

DataView 组件功能的编程接口的成员的一个数专门用于满足该 DataView 的内容来自远程 URI 方案。 涓嬭浇包括在 DataView 使用 Web 服务的成员的列表。

注意示例代码下载的内容标题的自动提取-DataView 使用数据从一个远程 URI 不能完全理解 DataView 组件的整个 API。 许多其他成员存在以满足我将在以后的专栏中介绍的其他方案。

使用数据标题的自动提取-DataView,从一个远程 URI 浠 g 爜涓嬭浇绀轰緥显示加载页面时创建一个 DataView 的 JavaScript 代码。 在 DataView 配置为立即获取其数据,通过将调用指定的 Web 服务方法。

dataProvider 属性表示在数据源,而该 fetchOperation 设置要调用该方法。 最后,fetchParameters 是包含该方法的参数信息的字典对象。 将您设置它为 JavaScript 对象的每个属性与方法定义一个形参的名称相匹配。 特别,在前面的示例 GetQuotesFromConfig 该方法具有以下原型:

[OperationContract(Name="GetQuotesFromConfig")]
StockInfo[] GetQuotes(bool isOffline);

在 DataView 接收 HTML 模板来填充 $ 通过创建帮助器函数和数据已成功提取后,装满在模板中的任何占位符。


图 3 的 A 格式的数据绑定的 Web 页使用 AJAX 和 jQuery

代码示例还包含一个自定义的计时器对象,它定期刷新 jQuery 动画的模板。 当计时器刻度时,使用任何当前值排序新的提取操作,"脱机"复选框。 在"脱机"复选框表示是否 Web 服务应返回假股票和值或连接到现实世界金融服务以获取报价的股票,则返回 True。 该服务从配置文件中获取金融服务的 URL 和股票的列表。 (有关详细信息,请参阅源代码。)

下个月

图 3 显示了格式和动态数据绑定 ASP.NET AJAX 的页面使用客户端呈现将原始数据绑定到一个相对较复杂的 HTML 模板。 在 ASP.NET AJAX 4.0,您会发现功能强大的编程工具进行编码这类页不难度比执行传统的服务器端数据绑定。

图 3 所示的网页是仅在第和一个长的路径的最简单的步骤。 下个月,我将讨论更多的功能的丰富的模板和如何将 HTML 的模板中的逻辑,并我将探讨实时数据绑定。 请继续关注!

Dino Esposito 是一个架构师在 IDesign 和该 co-author 的"Microsoft.NET:构建企业应用程序"(Microsoft 按,2008年)。 基于在意大利,Esposito 是经常在世界各地的行业事件演讲者。 您可加入他的博客,网址为 weblogs.asp.net/despos