【原文地址】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控件.docASP.NET_AJAX入门系列:使用UpdatePanel控件.doc
ASP.NET AJAX入门系列UpdatePanel控件教程
ajax技术,无刷新技术 导读:ScriptManager控件包括在ASP.NET 2.0 AJAX Extensions中,它用来处理页面上的所有组件以及页面局部更新,生成相关的客户端代理脚本以便能够在JavaScript中访问Web Service,所有需要支持...
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技术慨述、实现异步局部更新页面、UpdatePanel编程功能、 PageRequestManager的使用方法、Timer控件、Control Toolkit方法、结合 OOP功能、如何在客户端JavaScript调用web服务、如何从...
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技术慨述、实现异步局部更新页面、UpdatePanel编程功能、 PageRequestManager的使用方法、Timer控件、Control Toolkit方法、结合 OOP功能、如何在客户端JavaScript调用web服务、如何从...
主要内容包括:ASP .NET AJAX技术慨述、实现异步局部更新页面、UpdatePanel编程功能、 PageRequestManager的使用方法、Timer控件、Control Toolkit方法、结合 OOP功能、如何在客户端JavaScript调用web服务、如何从...
主要内容包括:ASP .NET AJAX技术慨述、实现异步局部更新页面、UpdatePanel编程功能、 PageRequestManager的使用方法、Timer控件、Control Toolkit方法、结合 OOP功能、如何在客户端JavaScript调用web服务、如何从...
主要内容包括:ASP .NET AJAX技术慨述、实现异步局部更新页面、UpdatePanel编程功能、 PageRequestManager的使用方法、Timer控件、Control Toolkit方法、结合 OOP功能、如何在客户端JavaScript调用web服务、如何从...
本书以AJAX为核心阐述对象,介绍了它对JavaScript所做的各种扩展,还介绍了在ASP.NET环境下创建客户端应用所需的一些核心控件。通过大量的实例,本书详述了AJAX的内部机制,并且紧跟时代潮流,重点描述了如何依靠...
-采用和Asp.Net Ajax类似的处理方式,需要在配置文件Web.config增加一个httpModules。 -现在支持Response.Redirect,你可以选择Response.Redirect或者ExtAspNet.PageContext.Redirect重定向页面,两者效果一样。 -...
这部分是ASP.NET AJAX的核心部分,包括了核心AJAX类型系统,网络协议层(networking stack),组件模型,扩展器(extender)基类,以及与ASP.NET集成的服务器端功能(包括广受欢迎的ScriptManager,UpdatePanel,和 Timer...
第一篇 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概述 第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操作实例! 值得下载看看!资源免费,大家分享!!
ASP.NET AJAX深入浅出系列课程(3):UpdatePanel的使用(下)_Demo.zip
UpdatePanel的简单用法: 局部更新是ajax技术的最基本,也是最重要的用法,今天大概把asp.net ajax中的局部更新控件 updatepanel的用法记录下,大家可以共同探讨
主要内容包括:ASP .NET AJAX技术慨述、实现异步局部更新页面、UpdatePanel编程功能、 PageRequestManager的使用方法、Timer控件、Control Toolkit方法、结合 OOP功能、如何在客户端JavaScript调用web服务、如何从...