`
lovnet
  • 浏览: 6714591 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

技巧和诀窍:在不用UpdatePanel的情形下可与ASP.NET AJAX 使用的酷UI模板技术

阅读更多

【原文地址】Tip/Trick: Cool UI Templating Technique to use with ASP.NET AJAX for non-UpdatePanel scenarios
【原文发表日期】 Sunday, October 22, 2006 9:02 PM

这个周末我一直饶有兴趣地在玩ASP.NET AJAX Beta版

通常情形下,当我把AJAX功能集成进我的编码时,我最后总是使用 ASP.NET AJAX 提供的内置服务器端控件(譬如UpdatePanel和UpdateProgress等)以及ASP.NET AJAX控件工具包里的那些酷控件。Scott Hanselman 两个星期前在他最近的一次 podcast 中采访我时开玩笑地声称,使用这些AJAX控件简直是“(cheating)”, 因为在大多数常见的情形下,它们不需要你写任何的客户端JavaScript编码。

这个周末,我决定把我的编程集中在 ASP.NET AJAX 框架中根本不使用UpdatePanel的一些客户端JavaScript 库函数上,试验另外的方式用服务器来轻松地产生HTML UI,然后把这些HTML通过AJAX动态地注入页面内。在这个过程中,我建立了一个我认为是比较有用的库,这个库可以和ASP.NET AJAX 以及其他 AJAX 库一起使用,来提供一个很好的ASP.NET模板UI机制,它不使用也不需要象 postback 和 viewstate 这样的概念,但仍旧提供了控件封装和简易重用的好处。

首先,ASP.NET AJAX中JavaScript 网络层(Networking Stack)的一些简短的背景知识

在开始讨论我上面提到的模板方法之前,先提供一些ASP.NET AJAX中客户端JavaScript库方面的背景知识,让我们首先来创建一个简单的AJAX "hello world" 应用。这个应用允许用户输入一个名字,点击一个按钮,然后在客户端使用JavaScript向服务器做一个AJAX调用,进而输出一个消息:

ASP.NET AJAX 包含了一个非常灵活的JavaScript 网络库 (network library stack),对.NET 数据类型有着丰富的序列化支持。你可以在服务器端定义可从客户端JavaScript 里调用的方法,要么是你的 ASP.NET 页面类里的静态方法,要么给你的ASP.NET应用添加一个web服务,这个服务须饰以 [Microsoft.Web.Script.Services.ScriptService] 元数据属性,而呈示的方法则须饰以标准的 [WebMethod] 属性。

例如,下面是个SimpleService.asmx web服务,内含一个GetMessage方法,该方法接受一个字符串参数:

usingSystem;
usingSystem.Web.Services;

[Microsoft.Web.Script.Services.ScriptService]
publicclassSimpleService:WebService{

[WebMethod]
publicstringGetMessage(stringname){
return"Hello<strong>"+name+"</strong>,thetimehereis:"+DateTime.Now.ToShortTimeString();
}
}

ASP.NET AJAX 然后可以自动创建一个JavaScript代理类,可在客户端用来调用这个方法,以及传递合适的参数。添加这个JavaScript代理类最容易的方法是在页面上添加一个 <asp:ScriptManager> 控件,然后指向web服务的端点。(这个控件同时也确保每个库在页面只被加载一次。)

然后我就可以调用这个方法,把文本框里的值传给它,用象下面这样的客户端 JavaScript 编码设置好一个回调事件处理器,定在服务器响应时触发。注:我可以把 JavaScript 编码写得更加花哨,去掉其中的几行代码,但我目前是故意要保持清晰和简单,以避免故弄玄虚:

<html>
<headid="Head1"runat="server">
<title>HelloWorldService</title>
<linkhref="StyleSheet.css"rel="stylesheet"type="text/css"/>

<scriptlanguage="javascript"type="text/javascript">

functioncallServer(){
SimpleService.GetMessage($get("Name").value,displayMessageCallback);
}

functiondisplayMessageCallback(result){
$get("message").innerHTML=result;
}

</script>

</head>
<body>
<formid="form1"runat="server">

<asp:ScriptManagerID="ScriptManager1"runat="server">
<Services>
<asp:ServiceReferencePath="~/SimpleService.asmx"/>
</Services>
</asp:ScriptManager>

<h1>HelloWorldExample</h1>

<div>
EnterName:<inputid="Name"type="text"/>

<ahref="BLOCKED SCRIPTcallServer()">CallServer</a>

<divid="message"></div>
</div>

</form>
</body>
</html>

这样,当我运行这个页面,输入一个名字,Scott,页面就会使用AJAX 回调,动态更新页面上的HTML,而不需要任何postback或页面更新。

使用模板产生HTML的一个比较干净的的做法

你可以从上面的例子看出,我可以很轻松地从服务器端返回HTML,在客户端把它注入页面。但是,我的这个做法的一个缺点是,我把生成HTML的逻辑直接参杂到我的服务器web method里了。这个做法不好,因为,1) 混杂了UI和逻辑编码,2) 随着 UI 愈加丰富,编码将会变得难以维护和编写。

我想要的是一个简易的方法,在我的web service方法里执行我的逻辑,获取数据,然后把数据传给某个模板或视图类来生成要返回的 HTML UI 结果。譬如,考虑生成一个客户/订单管理的应用,在其中使用AJAX来生成类似这样的一个客户列表UI:

我想要在我的 WebService 里编写象下面这样的服务器端编码来按国家查询客户,然后返回一个合适的HTML列表UI。注意到下面的ViewManager.RenderView 方法是如何允许我传进一个数据对象来绑定UI的。所有的UI生成编码都移出了我的控制器webmethod,都封装在我的View里了:

[WebMethod]
publicstringGetCustomersByCountry(stringcountry)
{
CustomerCollectioncustomers =DataContext.GetCustomersByCountry(country);

if(customers.Count>0)
returnViewManager.RenderView("customers.ascx",customers);
else
returnViewManager.RenderView("nocustomersfound.ascx");
}

结果是,这并不是很难,只需要20行左右的代码就实现了 ViewManager 类和上面用到的 RenderView 方法。你可以在这里下载这个简单的实现

我的实现允许你使用标准的ASP.NET 用户控件 (.ascx 文件)模型来定义一个显示模板,这意味著你拥有完全的VS设计器支持, intellisense,和编译检查。它并不要求你一定要用一个页面来包含这个用户控件,实际上,我的 RenderView 实现在显示时动态地生成一个空Page对象来包含这个用户控件,把显示记录下来,以一个字符串的形式返回。

譬如,下面这个Customer.ascx模板,我可以用它来生成象上面那个截图里的客户列表输出。它生成了一串客户的名字,每个客户有一个连接,指向他们的订单历史细节:

<%@ControlLanguage="C#"CodeFile="Customers.ascx.cs"Inherits="Customers"%>

<divclass="customers">

<asp:RepeaterID="Repeater1"runat="server">
<ItemTemplate>

<div>
<ahref="BLOCKED SCRIPTCustomerService.GetOrdersByCustomer('<%#Eval("CustomerID")%>',displayOrders)">
<%#Eval("CompanyName")%>
</a>
</div>

</ItemTemplate>
</asp:Repeater>

</div>

相关的后端代码是这样的(注,如果我想的话,我可以往里面添加特定视图的格式化方法):

usingSystem;

publicpartialclassCustomers:System.Web.UI.UserControl
{
publicobjectData;

voidPage_Load(objectsender,EventArgse)
{
Repeater1.DataSource=Data;
Repeater1.DataBind();
}
}

为了把数据传进模板,(譬如,上面这个customers 集合),我一开始时要求每个UserControl 实现一个IViewTemplate 接口,通过它我可以将数据与UserControl 相关联。但玩了一阵后,我决定使用一个更简单的用户模型,让UserControl 呈示一个如上面所示的公开的Data属性。然后,ViewManager.RenderView 方法通过反射把传给它本身的数据对象与UserControl实例相关联,之后,UserControl的行为就象一个普通用户控件一样。

最后得到的结果是一个非常强有力而且简易的方式,它可以生成你想要的任何类型的HTML回复,而且非常干净地封装在.ascx 模板文件里了。

最后的加工

你可以在这里下载我最后建立的样例的完整编码。为好玩,我给上面那个客户列表例子另添加了功能,在按国家查询返回客户列表后,用户可以点击任何一个客户的名字,然后就跳出一个相应客户的订单表(还有他们下订单的日期)。这也是用我上面描述的方法完全通过AJAX来实现的:

整个应用在客户端只有8行JavaScript编码,在服务器端总共有15行编码(包括数据访问的所有代码)。所有的HTML UI生成编码是封装在4个.ascx模板文件里的,我可以从我的 webmethod 里按需加载这些模板文件并对其绑定我的数据:

点击这里下载ViewManager.RenderView的编码,如果你想看看,试用一下的话。

希望本文对你有所帮助,

Scott

分享到:
评论

相关推荐

    ASP.NET_AJAX入门系列:使用UpdatePanel控件.doc

    ASP.NET_AJAX入门系列:使用UpdatePanel控件.docASP.NET_AJAX入门系列:使用UpdatePanel控件.doc

    ASP.NET AJAX入门系列:使用UpdatePanel控件

    ASP.NET AJAX入门系列UpdatePanel控件教程

    ASP.NET AJAX

    ajax技术,无刷新技术 导读:ScriptManager控件包括在ASP.NET 2.0 AJAX Extensions中,它用来处理页面上的所有组件以及页面局部更新,生成相关的客户端代理脚本以便能够在JavaScript中访问Web Service,所有需要支持...

    ASP.NET_AJAX入门系列

    ASP.NET_AJAX入门系列:概述.doc ASP.NET_AJAX_在Web开发中的应用.doc ASP.NET_AJAX入门系列:Timer控件简单使用....ASP.NET_AJAX入门系列:在母版页中使用UpdatePanel.doc ASP.NET_AJAX入门系列:自定义异常处理.doc

    ASP.NET AJAX经典范例168 VC#版 (代码) Part 12

    主要内容包括:ASP .NET AJAX技术慨述、实现异步局部更新页面、UpdatePanel编程功能、 PageRequestManager的使用方法、Timer控件、Control Toolkit方法、结合 OOP功能、如何在客户端JavaScript调用web服务、如何从...

    ASP.NET AJAX实战源码

    4.1 ASP.NET开发人员的Ajax 86 4.2 改进原有ASP.NET网站 87 4.2.1 一个示例ASP.NET网站 88 4.2.2 配置现有的ASP.NET网站 88 4.3 ScriptManager: Ajax页面的大脑 90 4.3.1 理解ScriptManager 90 4.3.2 部署...

    ASP.NET AJAX经典范例168 VC#版 (代码) Part 7

    主要内容包括:ASP .NET AJAX技术慨述、实现异步局部更新页面、UpdatePanel编程功能、 PageRequestManager的使用方法、Timer控件、Control Toolkit方法、结合 OOP功能、如何在客户端JavaScript调用web服务、如何从...

    ASP.NET AJAX经典范例168 VC#版 (代码) Part 11

    主要内容包括:ASP .NET AJAX技术慨述、实现异步局部更新页面、UpdatePanel编程功能、 PageRequestManager的使用方法、Timer控件、Control Toolkit方法、结合 OOP功能、如何在客户端JavaScript调用web服务、如何从...

    ASP.NET AJAX经典范例168 VC#版 (代码) Part 14

    主要内容包括:ASP .NET AJAX技术慨述、实现异步局部更新页面、UpdatePanel编程功能、 PageRequestManager的使用方法、Timer控件、Control Toolkit方法、结合 OOP功能、如何在客户端JavaScript调用web服务、如何从...

    ASP.NET AJAX经典范例168 VC#版 (代码) Part 8

    主要内容包括:ASP .NET AJAX技术慨述、实现异步局部更新页面、UpdatePanel编程功能、 PageRequestManager的使用方法、Timer控件、Control Toolkit方法、结合 OOP功能、如何在客户端JavaScript调用web服务、如何从...

    [ASP.NET.AJAX编程参考手册(涵盖ASP.NET.3.5及2.0)].(美)霍斯拉维.扫描版.pdf

    本书以AJAX为核心阐述对象,介绍了它对JavaScript所做的各种扩展,还介绍了在ASP.NET环境下创建客户端应用所需的一些核心控件。通过大量的实例,本书详述了AJAX的内部机制,并且紧跟时代潮流,重点描述了如何依靠...

    专业的ASP.NET控件,原生的AJAX支持,丰富的UI效果。

    -采用和Asp.Net Ajax类似的处理方式,需要在配置文件Web.config增加一个httpModules。 -现在支持Response.Redirect,你可以选择Response.Redirect或者ExtAspNet.PageContext.Redirect重定向页面,两者效果一样。 -...

    ASP.NET AJAX 入门教程

    这部分是ASP.NET AJAX的核心部分,包括了核心AJAX类型系统,网络协议层(networking stack),组件模型,扩展器(extender)基类,以及与ASP.NET集成的服务器端功能(包括广受欢迎的ScriptManager,UpdatePanel,和 Timer...

    完全手册:ASP.net Ajax电子教程(1-8章)

    第一篇 ASP.NET AJAX概述 第1章 初识ASP.NET AJAX  1.1 ASP.NET AJAX概述  1.1.1 ASP.NET和ASP.AJAX  1.1.2 ASP.AJAX服务器端架构  1.1.3 ASP.AJAX客户端架构  1.2 搭建ASP.NET AJAX开发环境  1.3 第一个ASP...

    完全手册:ASP.net Ajax电子教程(9-15章)

    第一篇 ASP.NET AJAX概述 第1章 初识ASP.NET AJAX  1.1 ASP.NET AJAX概述  1.1.1 ASP.NET和ASP.AJAX  1.1.2 ASP.AJAX服务器端架构  1.1.3 ASP.AJAX客户端架构  1.2 搭建ASP.NET AJAX开发环境  1.3 第一个ASP...

    Ajax结合GridView、UpdatePanel的ASP.NET操作实例

    Ajax结合GridView、UpdatePanel的ASP.NET操作实例! 值得下载看看!资源免费,大家分享!!

    ASP.NET AJAX深入浅出系列课程(3):UpdatePanel的使用(下)_Demo.zip

    ASP.NET AJAX深入浅出系列课程(3):UpdatePanel的使用(下)_Demo.zip

    asp.net UpdatePanel的简单用法

    UpdatePanel的简单用法: 局部更新是ajax技术的最基本,也是最重要的用法,今天大概把asp.net ajax中的局部更新控件 updatepanel的用法记录下,大家可以共同探讨

    ASP.NET AJAX经典范例168 VC#版 (代码) Part 6

    主要内容包括:ASP .NET AJAX技术慨述、实现异步局部更新页面、UpdatePanel编程功能、 PageRequestManager的使用方法、Timer控件、Control Toolkit方法、结合 OOP功能、如何在客户端JavaScript调用web服务、如何从...

Global site tag (gtag.js) - Google Analytics