ASP.NET AJAX

概述

ASP.NET AJAX 4.0 为 Web 应用程序引入了不同级别的功能,将进一步提高开发人员开发这些应用程序的效率。客户端模板提供了出众的应用程序灵活性和开发速度,可以轻松地将数据绑定到各种元素。全新的 DataView 控件允许您将模板扩展到整个数据列表。标记扩展允许您方便快捷地操作模板引擎的行为。自定义行为可用于处理复杂逻辑,而不用在过度复杂的条件属性中实现该逻辑。

目标

在本次动手实验中,您将学习如何:

•              利用全新的客户端模板将数据轻松绑定到您的用户界面。

•              使用 DataView 控件在客户端呈现数据。

•              通过创建自定义标记扩展,扩展模板引擎。

•              声明式地实例化行为和控件。

               

系统要求

您必须拥有以下工具才能完成本实验:

•              Microsoft Visual Studio 2008 或 2010。

•             ASP.NET  4.0 Preview 4AJAX

               

安装

您必须执行以下步骤来为本实验做好准备。主要包括下载和安装 ASP.NET AJAX 4.0 库。

1.            打开 web 浏览器,然后导航到 http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24645 并下载最新的安装文件。最新版本为 ASP.NET AJAX Preview 4。

2.            将下载的文件(Asp.Net_Ajax_Preview_4.zip)解压到机器上的已知位置。

               

练习

本动手实验室包括以下练习:

1.            使用客户端模板将数据绑定到用户界面 (UI)。

2.            使用 DataView 控件在客户端呈现数据。

3.            通过创建自定义标记扩展,扩展模板引擎。

4.            声明式地实例化行为。

               

注意:在本实验中,您将在已有代码的基础上进行更新或修改。本实验中的代码片段将会突出显示,帮助您准确理解需要修改的地方。

举例来说,以下代码片段将在已有 ASP 代码中添加一个 ScriptManager 元素。

 

完成本实验的估计时间:60 分钟。

初始材料

这次动手实验包括以下初始材料。

•              初始 AJAX 框架解决方案可以在第一个练习的 begin 文件夹中找到。

注意:本实验的示例文件包括一个 end 文件夹,其中包含完成练习后的最终解决方案。如果需要其他帮助来完成练习,您可以使用该解决方案作为指南。

               

下一步

练习 1:利用客户端模板

               

练习 1:利用客户端模板

在本练习中,您将使用全新的客户端模板引擎迅速将数据绑定到您的 UI 元素。

任务 1 - 向您的 ASP.NET 项目添加 ASP.NET AJAX 4.0

在本任务中,您将从框架 ASP.NET Web Application 入手,为它添加新的 ASP.NET AJAX 4.0 库。

1.            从 Start | All Programs | Microsoft Visual Studio 2010 | Microsoft Visual Studio 2010 打开 Microsoft Visual Studio 2010。

2.            在 Visual Studio Start Page 中,单击 Open Project 按钮。

 

图 1

打开项目

3.       在  Open Project 对话框中,打开 WebApplication1.sln 解决方案文件。默认情况下,该文件位于以下文件夹:%TrainingKitInstallFolder%\Labs\AspNetAjax\Source\Ex01-ClientSideTemplates\begin\.

4.            此时,解决方案结构应如图 2 所示。

 

图 2

框架解决方案结构

5.            打开 Windows 资源管理器窗口并导航到存储 ASP.NET AJAX 4.0 文件的位置。

注意:ASP.NET AJAX 4.0 文件包含一系列 JavaScript 文件和一个 README 文件,您可以从在本实验的安装过程中下载和解压的 .zip 文件中找到它们。

6.            使用 Windows 资源管理器,将以下 ASP.NET AJAX 文件拖到 scripts 目录中。

◦              MicrosoftAjax.js

◦              MicrosoftAjax.debug.js

◦              MicrosoftAjaxTemplates.js

◦              MicrosoftAjaxTemplates.debug.js

添加了新文件之后,您的解决方案结构应如图 3 所示。

 

图 3

添加 ASP.NET AJAX 文件后的解决方案结构

注意:ASP.NET AJAX 4.0 版本包括一个发行版和一个调试版的 AJAX 4.0。调试版适合在开发时使用,因为它包括注释、格式等。发行版则删除了空格和注释以节省空间,因为更适合生产使用。

使用 ScriptManager 控件注册脚本之后,它会自动确定呈现调试版或发行版。有关其工作原理的详细信息,请阅读以下文章:http://msdn.microsoft.com/en-us/library/system.web.ui.scriptmanager.scriptmode.aspx

7.            在 Visual Studio 中,打开 Default.aspx 页面并在 form 标记内添加一个 ScriptManager 元素。

ASPX

<body>

<form id="form1" runat="server">

    <asp:ScriptManager ID="scriptManager" runat="server" AjaxFrameworkMode="Explicit">

    </asp:ScriptManager>

      …

</form>

</body>

注意: ScriptManager 类的 MicrosoftAjaxMode 属性指定如何将 Microsoft ASP.NET AJAX 客户端库的客户端脚本包括在客户端中。可能的值应包括:Enabled、 Disabled 和 Explicit.Explicit 选项指定您将包含对各个框架核心脚本文件的脚本引用,以及对每个脚本文件需要的依赖关系的引用。

8.            接下来,在 ScriptManager 元素中,为 SampleData.js、ASP.NET AJAX 脚本、jquery-1.2.3-min.js 和 CustomScripts.js 文件添加 ScriptReference 元素。注意,ScriptReference 元素包含在 Scripts 元素中。

ASPX

<asp:ScriptManager ID="scriptManager" runat="server" AjaxFrameworkMode="Explicit">

  <Scripts>

    <asp:ScriptReference Path="~/scripts/MicrosoftAjax.js" />

    <asp:ScriptReference Path="~/scripts/MicrosoftAjaxTemplates.js" />

    <asp:ScriptReference Path="~/scripts/SampleData.js" />

    <asp:ScriptReference Path="~/scripts/jquery-1.2.6.min.js" />

    <asp:ScriptReference Path="~/scripts/CustomScripts.js" />

  </Scripts>

</asp:ScriptManager>

注意:只有 MicrosoftAjax.js 和 MicrosoftAjaxTemplates.js 文件是 ASP.NET AJAX 4.0 发行版的一部分。jQuery 文件将包含在 Visual Studio 2010 中,另外两个引用的文件用于保存静态示例数据,以及为本实验定义自定义 JavaScript 代码。

               

任务 2 –添加客户端模板

在此任务中,您将添加一个基本的客户端模板到页面中,并使用从模拟 AJAX 调用中检索的一些数据填充它。

我们首先将在页面底部添加一个新的客户端模板,然后使用 JavaScript 关联一些事件处理程序,以处理 UI 交互和填充模板。

1.            在 Default.asxp 文件中,添加一个客户端模板,用于显示关于 org-chart 中的特定员工的详细信息。在结束 </body> 标记上方添加模板标记。

ASPX

</form>

  …

  <div id="details-template" class="sys-template">

    <h3>Details for {{ Name }}</h3>

    <p>Has reports?{{ Reports == null ?'No' :'Yes' }}</p>

  </div>

</body>

注意:以上代码片段中有一些项需要说明一下。

<div> 元素的 class  属性设置为 sys-template。这是一个约定,用于向最终用户隐藏初始模板。您应该在 CSS 样式表中将这个类定义为 {visibility:hidden; display:none;}。

数据字段将通过 {{ }}  结构(比如说 {{  Name }})注入到模板标记中。可以将它们保存在文本节点中的任意位置,或者保存为属性的值。这些结构可以包含任意 JavaScript 表达式,只要该表达式可以计算为字符串。

2.            如果现在运行应用程序,应该会看到一个非常简单的页面,其中包含一些简单的标题文本,以及一个包含一些员工的 org 表。

 

图 4

一个非常基本的页面

3.            现在,单击 Get Details 按钮不会执行任何任务,因为我们并未将任何操作与这些按钮绑定,如以下标记所示。

ASPX

<input id="detailsBtn-123" type="button"

value="Get Details" name="123" />

<input id="detailsBtn-987" type="button"

value="Get Details" name="987" />

注意:此标记将作为框架的一部分提供。在实际的应用程序中,这种标记会动态生成在服务器上,并传递给客户端。我们在此处将使用静态标记来确保实验的简单性和专一性。

4.            导航到 CustomScripts.js 文件并为两个按钮的单击事件关联事件处理程序。

JavaScript

Sys.Application.add_load(function()

{

  $("#managers input").click(fetchAndShowDetails);

});

注意: add_load 方法允许我们定义一个函数来在 DOM 完成加载时运行。在以上代码中,我们触发了一个匿名函数。这个匿名方法调用 jQuery 的 $(…) 函数来解析 DOM,并返回与传入 CSS 选择器相匹配的元素。在本例中,我们将获取元素中 id 与管理器相同的所有输入元素,并将 fetchAndShowDetails 函数关联为这些输入按钮的 OnClick 事件的处理程序。

您可以在此处找到关于 jQuery API 的更多信息:http://docs.jquery.com/。

5.            我们还需要创建 fetchAndShowDetails 函数。

JavaScript

function fetchAndShowDetails(eventElement)

{

  var container = $get("details-container");

  clearContainer(container);

 

  var manager = getManagerWithId(eventElement.target.name);

  var detailsTemplate = new Sys.UI.Template($get("details-template"));

  detailsTemplate.instantiateIn(container, manager);

   

  $(container).show();

}

注意:以上代码的中间部分将为我们的文本建立一个空的容器。然后,我们通过 getManagerWithId 方法获取关于管理器的一些数据。接下来,我们通过 $get 方法获取 details-template,并将它传递给 Sys.UI.Template 构造函数以解析模板。

最后,我们使用 instantiateIn 方法将管理器数据推入到容器中。

getManagerWithId 和 clearContainer 函数都已作为本实验的框架的一部分提供。第一个函数模拟一个调用来收集数据(可能从 AJAX 回调服务器),第二个函数将容器元素重置为初始(空的、隐藏)状态。

6.            如果现在运行应用程序,您应该会看到与之前相同的空白页面。但是,单击任意一个 Get Details 按钮都会触发针对该员工的详细信息的模拟请求,然后将该数据应用于模板。AJAX

 

图 5

应用于模板的数据。

               

下一步

练习 2:使用 DataView 控件

               

练习 2:使用 DataView 控件

我们完成的工作很有趣并且非常有用,但它只是一个非常简单的模板应用示例。模板非常简单,比如练习 1 中所使用的模板就非常适合用于呈现较小的 UI 部分,但如果要绑定较复杂的数据,它们会变得混乱且难以维护。

一个比较复杂的使用数据的例子是,我们希望绑定一个数据列表,比如向管理人员报告的一组员工(在本例中为 Drew 和 Phil)。这时,我们需要编写一些循环逻辑来遍历列表,并将各个报告绑定到模板的新实例。

ASP.NET AJAX 4.0 包括一个绑定控件 DataView, 它可以利用模板并对它应用整个列表的数据,对列表中的各个数据重复应用该模板。我们将使用 DataView 来呈现报告者的各个管理人员列表。

任务 1 –将 DataView 添加到客户端模板

在此任务中,您将添加一个嵌入模板到在练习 1 创建的基本客户端模板中,然后使用 DataView 将新模板绑定到数据列表。

1.            从 Start | All Programs | Microsoft Visual Studio 2010 | Microsoft Visual Studio 2010 打开 Microsoft Visual Studio 2010。

1.            打开 WebApplication1.sln 解决方案文件。默认情况下,该文件位于以下文件夹:%TrainingKitInstallFolder%\Labs\AspNetAjax\Source\Ex02-UsingDataView\begin\。您也可以继续使用上一个练习完成时获得的解决方案。

2.            导航到 Default.aspx 页面,并添加一个嵌入模板到在Exercise 1

ASPX

<div id="details-template" class="sys-template">

<h3>Details for {{ Name }}</h3>

<p>Has reports?{{ Reports == null ?'No' :'Yes' }}</p>

  <h4>Reports:</h4>

  <ul class="sys-template">

    <li>{{Name}} ({{ Title }})</li>

  </ul>

</div>

3.            现在,我们需要使用 DataView 将该模板绑定到数据列表。因此,导航到 CustomScripts.js 文件并修改 fetchAndShowDetails 函数,在已有的 instantiateIn 调用后添加一个新的$create 调用。

JavaScript

function fetchAndShowDetails(eventElement)

{

var container = $get("details-container");

clearContainer(container);

 

var detailsTemplate = new Sys.UI.Template($get("details-template"));

var manager = getManagerWithId(eventElement.target.name);

detailsTemplate.instantiateIn(container, manager);

 

  $create(Sys.UI.DataView,

          { data:manager.Reports },

          {},

          {},

          $('ul', container)[0]);

 

$(container).show();

}

注意:在以上代码中,我们将使用全局可用的 $create 函数创建一个 DataView 控件,传递一组管理人员的报告者作为要绑定的数据项,还会传递应将数据绑定到的模板。

我们使用 jQuery’s $(…) 函数获取模板元素的句柄,以获取容器元素中的所有无序列表。然后,接受该数组中的第一个(在本例中也是唯一一个)元素。现在,我们为本练习开始时创建的嵌入模板创建了一个句柄。

4.            运行应用程序,并单击顶部的 Get Details 按钮。您应该会注意到,我们现在不仅显示了 Drew 的详细信息,还显示了他的报告列表。

 

图 7

通过 DataView 绑定嵌入模板

5.            现在,单击下文的 Get Details 按钮,您会注意到仍然显示了 Reports: 标题,但我们提供了一个空列表,我们将在下一个任务中清理这种 UI 不一致性。

 

图 8

嵌入模板未绑定到任何数据

               

任务 2 –更智能地标记模板

在此任务中,我们将继续扩展模板的功能。 我们将根据不断变化的数据条件更改显示。

1.            首先,向原始详细信息模板添加第二个嵌入模板,它与上面的任务中添加的模板之间属于平等关系。这个新模板将保存一条警告消息,用于在没有要显示的报告时显示。

ASPX

<div id="details-template" class="sys-template">

<h3>Details for {{ Name }}</h3>

<p>Has reports?{{ Reports == null ?'No' :'Yes' }}</p>

<h4>Reports:</h4>

<ul class="sys-template">

<li>{{Name}} ({{ Title }})</li>

</ul>

  <p class="sys-template warning-message">

    It looks like {{ Name }} has no reports.</p>

</div>

2.            在 CustomScripts.js 文件中,我们需要更新 fetchAndShowDetails 方法,以针对报告或警告消息有条件地显示模板。我们首先将定义一个使用 manager 的新方法,以及一些 container 元素来确定要显示哪些模板。

JavaScript

function renderReportsList(manager, container)

{

    var dataItem, element;

    if (manager.Reports == null) {

        dataItem = manager;

        element = $('.warning-message', container)[0];

    }

    else {

        dataItem = manager.Reports;

        element = $('ul', container) [0];

    }

    $create(Sys.UI.DataView,

          { data:dataItem },

            {},

            {},

            element);

}

3.            现在,重构 fetchAndShowDetails 函数,使用新的 renderReportsList 方法来绑定和显示适当的模板。

JavaScript

function fetchAndShowDetails(eventElement)

{

var container = $get("details-container");

clearContainer(container);

 

var manager = getManagerWithId(eventElement.target.name);

var detailsTemplate = new Sys.UI.Template($get("details-template"));

detailsTemplate.instantiateIn(container, manager);

 

  renderReportsList(manager, container);

               

$(container).show();

}

4.            运行应用程序,然后单击上方的 Get Details 按钮。您应该能像之前那样看到 Drew 的报告列表。

5.            现在,单击下方的 Get Details 按钮,您会注意到我们使用一条警告消息填充了之前的空白区域。

 

图 9

有条件地条件绑定到模板

               

任务 3 –使用条件属性

在此任务中,您将了解如何通过属性有条件地显示内容格式。

1.            导航到 Default.aspx 页面,并更改无序列表中的列表项,让它们使用条件属性将 CSS 类设置为 fired (当绑定到员工的数据项的 Fired 属性设置为 True 时)。

注意:CSS 类 fired 在框架的某个文件中定义。但是,添加此代码会触发 HTML 警告,提示 fired 不是有效的属性。您可以忽略此警告,因为它不会影响应用程序的功能。

ASPX

<div id="details-template" class="sys-template">

<h3>Details for {{ Name }}</h3>

<p>Has reports?{{ Reports == null ?'No' :'Yes' }}</p>

<h4>Reports:</h4>

<ul class="sys-template">

    <li class:fired={{Fired}}>

{{Name}} ({{ Title }})

</li>

</ul>

<p class="sys-template warning-message">

It looks like {{ Name }} has no reports.</p>

</div>

2.            运行应用程序,并单击上方的 Get Details 按钮。您应该会看到列表中的第二行是个叉号,用于表示该员工已被解雇!

 

图 10

应用条件属性

               

下一步

练习 3:创建自定义标记扩展

               

练习 3:创建自定义标记扩展

模板特性是可扩展的,它支持创建可用作模板标记中的属性和文本节点的自定义表达式。

标记扩展包括三项:目标组件的 JavaScript 函数、目标属性的名称以及一个属性包(包含扩展表达式上的属性集)。

注意:属性包还包含三个自动属性:

1) $default,指定后将包含表达式的默认无名称属性

2) $dataItem,当前的数据项

3) $id,用于创建唯一标识符的函数

表达式采用以下形式:

{expressionName defaultParameter, parameterName1=parameterValue1, parameterName2=parameterValue2[, ...]}

任务 1 –通过标记扩展设置属性值

在显示列表项时,一个常见的需求是用不同颜色交替表示列表中各行的背景。为此,我们将创建一个 alternate 标记扩展,它将返回一个 CSS 类,可用于为列表中第奇数个和第偶数个元素设置不同的样式。

1.            从 Start | All Programs | Microsoft Visual Studio 2010 | Microsoft Visual Studio 2010 打开 Microsoft Visual Studio 2010。

2.            打开 WebApplication1.sln 解决方案文件。默认情况下,该文件位于以下文件夹:%TrainingKitInstallFolder%\Labs\AspNetAjax\Source\Ex03-CustomMarkupExtensions\begin\。您也可以继续使用上一个练习完成时获得的解决方案。

3.            导航到 CustomScripts.js 文件并为 alternate 标记扩展添加以下代码。

JavaScript

function alternate(component, attribute, args)

{

  return args["$index"] % 2 ?"even" :"odd";

}

4.            现在,我们需要通过 ASP.NET AJAX 框架注册 alternate 表达式。为此,更新 CustomScripts.js 文件中的 Sys.Application.add_load 函数,添加一个 Sys.Application.registerMarkupExtension 调用。

JavaScript

Sys.Application.add_load(function()

{

    Sys.Application.registerMarkupExtension("alternate", alternate);

$("#managers input").click(fetchAndShowDetails);  

});

5.            要在模板中使用此标记扩展,需要添加一个值为 {alternate} 的类属性到内部 <li> 元素中。

ASPX

<div id="details-template" class="sys-template">

<h3>Details for {{ Name }}</h3>

<p>Has reports?{{ Reports == null ?'No' :'Yes' }}</p>

<h4>Reports:</h4>

<ul class="sys-template">

    <li class="{alternate}" class:fired="{{Fired}}">

{{Name}} ({{ Title }})

</li>

</ul>

</div>

6.            运行应用程序,然后单击上方的 Get Details 按钮。您应该能看到与之前相同的列表,但现在各行都具有交替的背景颜色。

 

图 11

通过标记扩展修改背景颜色

               

任务 2 –向标记扩展传递参数。

如上所述,标记表达式仅包括一个目标组件函数、目标属性的名称,以及一个属性包。通常,这三个自动包含在属性包中的属性并不足以满足您的需求,您需要传入自己的参数。

举例来说,上面任务 1 所定义的标记扩展非常简单,因此它始终返回字符串“even”或“odd”。但是,您也许希望在应用程序中共享这些标记扩展,或者作为较大的 JavaScript 库的一部分来实现其他目的。这时,该方法的用户可能会定义自己的 CSS 类供列表中的 even 或 odd 行使用。

那么如何实现此目的呢?向标记扩展传递一些自定义属性!

1.            导航到 CustomScripts.js 文件并更改 alternate 函数,以允许可选的 evenClass 和 oddClass 属性。

JavaScript

function alternate(component, attribute, args)

{

  var evenClass = (args["evenClass"] != null

    ? args["evenClass"] :"even");

  var oddClass = (args["oddClass"] != null

    ? args["oddClass"] :"odd");

  var cssClass = (args["$index"] % 2 ? evenClass :oddClass);

  return cssClass;

}

2.            回到 Default.aspx 页面;更新模板,传入您自己的 evenClass 和 oddClass 属性。

ASPX

<div id="details-template" class="sys-template">

<h3>Details for {{ Name }}</h3>

<p>Has reports?{{ Reports == null ?'No' :'Yes' }}</p>

<h4>Reports:</h4>

<ul class="sys-template">

    <li class="{alternate evenClass=std, oddClass=alt}"

      class:fired={{Fired}}>

{{Name}} ({{ Title }})

</li>

</ul>

</div>

3.            运行应用程序,请注意各行的背景颜色已经根据 default-styles.css 文件中的 .std 和 .alt CSS 类的定义发生了变化。

 

图 12

作为参数传递的替代 CSS 类

               

下一步

练习 4:声明式地实例化行为

               

练习 4:声明式地实例化行为

在之前的任务中,当报告的 Fired 属性为 true 时,我们使用条件属性设置了一个 CSS 类。这可以满足当时的需求,但现在,我们需要满足新的要求:我们需要根据 Fired 和 NewHire 属性分别设置 fired 或 newHire CSS 类。

我们可以使用另一个条件属性来实现此目的,但这种比较复杂的逻辑更加适合通过自定义行为来处理。自定义行为在 JavaScript 文件中创建,然后将绑定到 DOM  中的特定元素。在早期版本的 ASP.NET AJAX 中,这只能在 JavaScript 中完成,但在 ASP.NET AJAX 4.0 中,您可以声明性地关联行为与元素。

任务 1 –添加自定义行为

1.            从 Start | All Programs | Microsoft Visual Studio 2010 | Microsoft Visual Studio 2010 打开 Microsoft Visual Studio 2010。

2.            打开 WebApplication1.sln 解决方案文件。默认情况下,该文件位于以下文件夹:%TrainingKitInstallFolder%\Labs\AspNetAjax\Source\Ex04-DeclarativelyInstBehaviors\begin\。您也可以继续使用上一个练习完成时获得的解决方案。

3.            在 Solution Explorer 中,右键单击 Behaviors 目录,单击 Add | New Item 并选择 Visual C# | Web 类别和 Jscript File 模板。

4.            将文件名更改为 EmployeeStatus.js 并单击 Add 按钮。

 

图 13

添加 EmployeeStatus.js 文件之后的项目结构

5.            打开 EmployeeStatus.js 文件并添加以下代码以实现 EmployeeStatus 行为。

JavaScript

/// <reference name="MicrosoftAjax.js"/>

/// <reference path="../MicrosoftAjaxTemplates.js" />

Type.registerNamespace("WebApplication1");

WebApplication1.EmployeeStatus = function(element)

{

  WebApplication1.EmployeeStatus.initializeBase(this, [element]);

}

WebApplication1.EmployeeStatus.prototype =

{

  initialize:function()

  {

    WebApplication1.EmployeeStatus.callBaseMethod(this, "initialize");

    var currentElement = this.get_element();

    var employee = this.get_dataItem();

    if (employee.NewHire)

      $(currentElement).addClass("newHire");

    if (employee.Fired)

      $(currentElement).addClass("fired");

  }

};

注意:get_dataItem() 方法将返回 employee 对象,它允许我们查看该 employee 的状态,即 newHire 或者 fired。如果任何一个状态为 true,则对当前 DOM 元素应用适当的 CSS 类。我们将通过 get_element() 调用来检索该 DOM 元素。

6.            在 EmployeeStatus.js 文件的结束部分添加以下代码,将函数绑定到一个自定义行为。

JavaScript

WebApplication1.EmployeeStatus.registerClass(

    "WebApplication1.EmployeeStatus", Sys.UI.TemplateBehavior);

注意:ASP.NET AJAX 中的行为就是一个与 DOM 元素相关联的对象,它包含处理其底层元素的逻辑。Sys.UI.Behavior 类通过 get_element 方法实现对所绑定元素的访问。

由于我们还想要一个能够访问与相关 DOM 元素绑定的数据项的行为,因此我们将使用一个名为 Sys.UI.TemplateBehavior 的自定义行为。该类并不是 ASP.NET AJAX 的一部分,但它展示了如何创建一个自定义行为。它实现 Sys.UI.ITemplateContext 接口,并通过 get_dataItem 方法提供对底层数据项的访问。

               

任务 2 –使用自定义行为

在任务 1 中,我们将在一个单独的 JavaScript 文件中创建自定义行为。现在,我们需要在 ASP.NET 页面中实现它。

1.            导航到 Default.aspx 页面,并添加一个对新的 EmployeeStatus.js 文件和实验框架中已有的 TemplateBehavior.js 的脚本引用。

ASPX

<asp:ScriptManager ID="scriptManager" runat="server" AjaxFrameworkMode="Explicit">

<Scripts>

<asp:ScriptReference Path="~/scripts/MicrosoftAjax.js" />

<asp:ScriptReference Path="~/scripts/MicrosoftAjaxTemplates.js" />

<asp:ScriptReference Path="~/scripts/SampleData.js" />

<asp:ScriptReference Path="~/scripts/jquery-1.2.6.min.js" />

<asp:ScriptReference Path="~/scripts/CustomScripts.js" />

    <asp:ScriptReference Path="~/scripts/Behaviors/TemplateBehavior.js" />

    <asp:ScriptReference Path="~/scripts/Behaviors/EmployeeStatus.js" />

</Scripts>

</asp:ScriptManager>

2.            我们现在可以将 employeestatus 行为绑定到模板的内部 <li> 元素了。4.0 允许我们通过使用 sys:attach 属性声明性地完成此任务。这会将 employeestatus 行为附加到模板的 <li> 元素中。AJAX

注意:您可能已注意到 employeestatus 并不像 employeeStatus 那样是以驼峰式大小写形式表示的。这与通过命名空间引用行为的方式相关。我们将在下面讨论其原因。

ASPX

<div id="details-template" class="sys-template">

<h3>Details for {{ Name }}</h3>

<p>Has reports?{{ Reports == null ?'No' :'Yes' }}</p>

<h4>Reports:</h4>

<ul class="sys-template">

    <li class="{alternate evenClass=std, oddClass=alt}" sys:attach="employeestatus">

{{Name}} ({{ Title }})

</li>

</ul>

<p class="sys-template warning-message">

It looks like {{ Name }} has no reports.

</p>

</div>

注意:我们删除了用于确定是否应该将 CSS fired 添加到模板中的条件属性。该属性已不再需要,因为我们将它的功能替换成了更加复杂的 employeestatus 行为。

3.            现在,您应该会注意到模板的内部 <li> 元素上的 sys:attach 属性报告了一个无法识别命名空间的错误。

 

图 14

Unrecognized namespace 'sys'

4.            出现上述错误的原因是我们还没有引用命名空间。我们可以修复此问题,方法是将 Sys 命名空间添加到 <body> 标记中。其工作方式类似于服务器上的 @Register 指令。更新 Default.aspx 的 <body> 标记以修复此错误。

ASPX

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

注意:<body> 标记中的 sys 命名空间是许多系统属性的前缀。sys:attach 是其中一个系统属性,它用于指定要附加到元素的逗号分隔的控件或行为列表。

5.            与 sys 命名空间类似,我们需要在 <body> 标记中声明 employeestatus 行为来注册它。

ASPX

<body xmlns:sys="javascript:Sys" xmlns:employeestatus="javascript:WebApplication1.EmployeeStatus">

注意:employeestatus 命名空间声明根据 XHTML 标准全保留为小写形式,该标准禁止在名称空间声明中使用大写字符。虽然一些浏览器支持大小写混用,但最好依照 Web 标准尽可能确保兼容性。 

6.            运行应用程序,您会注意到列表中第一个员工已经变为粗体,这表示他是新员工。您还会注意到,第二项仍然显示为带有删除线的文本,表示员工已被解雇。

 

图 15

使用自定义行为设置新雇用和解雇的员工的 CSS 类

               

下一步

总结

               

总结

在本实验中,您了解了 ASP.NET AJAX 4.0 中的一些强大的新特性。您使用模板实现了快速内容格式化,并了解了 DataView 在使用模板处理数据列表方面的简便和强大,此外还了解了关于标记扩展的各种新功能。最后,您了解了如何使用自定义行为来扩展代码,以及将这些行为绑定到具体行为,以便提供复杂的 DOM 操作。