【IT168 技术文档】
以组件的思想重新审视Ajax客户端开发
在进入主题之前,我想和大家一起再来看一下本文章系列第一篇中的一个Demo:ASPNETAJAXTest。我现在将其中的客户端代码重新贴在这里。
Default.aspx:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Pagetitle>
head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Path="~/ajax.js" />
Scripts>
<Services>
<asp:ServiceReference Path="~/SayHelloService.asmx" />
Services>
asp:ScriptManager>
<div>
<input id="btnSayHello" type="button" value="SayHello" onclick="btnSayHello_onClick()" />
<div id="result">div>
</div>
</form>
</body>
ajax.js:
这是一种我们很熟悉的JavaScript编程模式:以DOM操作为基础。在这种编程模式下,所有页面元素被看成一个树状的DOM元素集合,不论是取得数据还是改变页面元素的属性,都要使用相应的DOM操作。例如我们要取得某个文本框中的值,则首先使用document.getElementById(在ASP.NET AJAX框架里可以缩写为$get)方法取得这个文本框的DOM引用,然后获取其value属性的值。
这种编程模式,很容易给我们造成困惑,例如文本框、复选框、提交按钮、普通按钮的DOM表示都是“input”元素,另外还要使用如innerHTML这样不是很直观的名字设置div或span的值。其实对于开发人员,尤其是长期从事服务器端开发的人员来说,我们更希望将文本框看做TextBox,将复选框看做CheckBox,将按钮看做Button,将div或span看做Label,而且,我们更希望使用label1.text这样的语句设置div中的文本,而不是使用innerHTML。
幸运的事,ASP.NET AJAX的开发人员显然考虑到了这一点,现在ASP.NET AJAX框架允许我们使用类似服务器端那种组件式的编程模式来进行客户端编程。
下面我们来看一下使用组件思想重新编写的这个应用。首先看一下aspx页面:
Default.aspx:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Pagetitle>
head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Assembly="Microsoft.Web.Preview" Name="PreviewScript.js" />
<asp:ScriptReference Path="~/ajax.js" />
Scripts>
<Services>
<asp:ServiceReference Path="~/SayHelloService.asmx" />
Services>
asp:ScriptManager>
<div>
<input id="btnSayHello" type="button" value="SayHello" />
<div id="result">div>
div>
form>24body>25html>
这里有两处变化,一是在ScriptManager控件里增加了对PreviewScript.js的引用。这里要注意,客户端组件的内容并不包含在ASP.NET AJAX1.0正式版里,而是包换在ASP.NET AJAX Futures CTP部分。所以,要使用这些功能,首先要添加对Microsoft.Web.Preview.dll文件的引用,这个文件在ASP.NET AJAX Futures CTP的安装目录里,然后要在页面中添加对PreviewScript.js文件的引用。
第二个变化是这里的btnSayHello已经没有了onclick属性,那么如何知道单击这个按钮的时候需要执行何种代码呢?答案在js文件里。
ajax.js:
var lblResult;
Sys.Application.add_init(onPageInit);
function onPageInit()
{ btnSayHello=new Sys.Preview.UI.Button($get("btnSayHello"));
btnSayHello.initialize();
lblResult=new Sys.Preview.UI.Label($get("result"));
lblResult.initialize(); btnSayHello.add_click(btnSayHello_onClick);
}
function btnSayHello_onClick(){
SayHelloService.SayHello(OnSucceeded,OnFailded);
}function OnSucceeded(resultText){
lblResult.set_text(resultText);
}function OnFailded(error){
lblResult.set_text("调用失败。错误信息:"+error.get_message());}
我们看到,应用组件编程思想后,JavaScript发生了巨大的改变。不着急,我们一步一步解析这个文件。
最顶上是定义了两个全局变量,这两个变量将分别存储对btnSayHello和result的引用。之所以要定义成全局变量,是方便在整个文件中调用两个控件。
Sys.Application.add_init(onPageInit);的作用是告诉页面当页面初始化时执行名为onPageInit的函数。
onPageInit是一个自定义函数,主要完成客户端控件的创建、初始化工作。以下面两行代码为例:
btnSayHello.initialize();
第一行我想大多数人一看就知道是什么意思,因为那个“new”实在太亲切了,这正是创建一个Button的实例,并将其赋给btnSayHello变量。其中Sys.Preview.UI.Button是Button的完全限定名,而大多数控件的构造函数都需要一个参数,用来指出这个控件要关联到的DOM元素。而第二行是必须的,在实例化一个控件后,最好马上调用initialize方法,避免一些奇怪的情况发生。
上面这行代码是将控件的单击事件与btnSayHello_onClick这个函数关联起来。这里我要专门说一下ASP.NET AJAX客户端控件的属性及事件的设置方法。
ASP.NET AJAX框架规定,在获取一个控件的属性时,应使用“控件名.get_属性名()”这种方法,而设置时则是“控件名.set_属性名()”。为一个控件的某个事件添加监听函数时,应该用“控件名.add_事件名()”,移除时用“控件名.remove_事件名()”。这是ASP.NET AJAX强制执行的命名规范,所有的客户端控件都遵从这个规则,以后我们在开发自己的客户端组件时,也应该遵从这个规则。
知道了以上知识,很多代码就很好理解了。例如“lblResult.set_text(resultText);”就是将lblResult控件的text属性设置为resultText。剩下的代码我就不解释了,应该没问题了。