1 以客户端为中心的Ajax应用
在进行Ajax应用开发的之前,通常我们首先要考虑一个问题,那就是此应用到底以客户端为中心还是以服务器端为中心。什么情况下应该以客户端为中心,而什么情况下应该以服务器端为中心呢?要回答这个问题首先我们要来看看它们各自的一些例子。
我们所见到的一部分Ajax网站,它们和非Ajax网站的结构是类似的,也就是由多个页面组成,一般一个视图就是一个页面,与非Ajax网站不同的地方仅在于引入了与服务器端的后台通信,而且这些通信逻辑通常仅服务于页面上一个局部的区域。例如一个社区的注册页面,输入用户名后自动在后台向服务器查询该用户名是否已被使用;又例如一个书评网站,在你通过选择星星的数量表明对一本书的评级之后,无需刷新页面就能后台保存你的选择。这些都是以服务器端为中心的Ajax应用例子,因为这些网站的逻辑大部分还是放在服务器端,必须在服务器端执行,只不过客户端通过引入后台通信机制增加了对用户的友善程度,减少了用户等待页面刷新的时间。
另外一些Ajax网站则不同,例如Gmail和PageFlakes,它们通常只有一个或者少数几个页面,大部分的逻辑都在客户端执行,服务器的作用仅在于提供数据以及执行少数在客户端执行会导致安全漏洞的操作。这些网站我们称之为以客户端为中心的Ajax应用。接下来我们就看看常见的以客户端为中心的Ajax应用的三种模型。
以客户端为中心的三种模型
我们都知道Ajax无非就是使用XMLHttpRequest对象发送请求给服务器,然后使用返回的数据更新页面上的内容。在这里,我们所能够发送和接收的数据其实都是纯文本的,因此我们能够做出的选择就是以什么样的格式去发送与接收数据。
以内容为中心
在已有的服务器端逻辑基础上,如何尽量少作出改动就能实现Ajax?可能很多人都能想到同样的结果,就是将原本整页输出的HTML改为仅仅输出内容更新过的一个局部,使用XHR获取这个局部HTML然后更新到页面上。这正是ASP.NET AJAX中的UpdatePanel控件所做的事情。因此XHR接收的是即将现实的HTML内容,因此被称之为以内容为中心的Ajax。
以脚本为中心
如果你觉得发送HTML到客户端,然后还要使用JavaScript才能更新到页面上,这还是麻烦,干脆把更新用的JavaScript也嵌入在发送的内容中就好了,也就是所谓的以脚本为中心的Ajax。脚本被XHR接收至客户端后,直接使用eval()执行,无需任何复杂的客户端逻辑。这种实现方式在ASP.NET AJAX/Futures中暂时没有直接的支持,因此也较少人使用。
以数据为中心
与以脚本为中心相反的做法就是,服务器端连HTML也不生成了,直接将数据发送至客户端,让客户端承担数据处理并生成对应HTML的工作。由于传输的是纯粹的数据,因此这被称之为以数据为中心的Ajax。
说到传输数据,我们面临的选择是数据格式,例如XML与JSON。XML固然好,因为.NET内置了众多的XML支持,并且.NET Web Service本身也就是使用XML的。然而客户端解释XML是一件很麻烦的事情,浏览器的DOM API提供的操作都非常有限,开发复杂应用时客户端解释XML所需的代码将变得非常繁多。
对于客户端来说,JSON则要有好得多,只需要放进eval()函数里,出来的便是解释好的JavaScript对象。同时,ASP.NET AJAX已经为.NET Web Service引入了JSON支持,因此在.NET作为服务器端框架的前提下JSON比XML更具优势
2 使用ASP.NET Futures开发以客户端为中心的Ajax应用
在使用ASP.NET Futures开发之前,我们首先要知道它是怎么工作的,以及它为我们提供了哪些基础部件以便于我们的开发。
ASP.NET Futures提供的客户端模型
首先,ASP.NET AJAX/Futures在客户端为我们提供了一种类似于服务器端的控件机制。你可以将一个<input type=”text” />初始化为一个Sys.UI.TextBox,然后它就如同服务器端的TextBox一样易于使用。
然后,ASP.NET Futures还提供了一种叫做Behavior的东东。什么是Behavior呢?你可以简单地认为Behavior就是一组事件、方法与对象的集合,这个集合是基于交互逻辑而聚合的,而非基于对象性质。例如现在有一个TextBox,你希望在其中输入前几个字母之后,TextBox会弹出下拉框提供若干可能的输入选项给你选择,也就是我们通常所说的AutoComplete(自动完成)。那么在这里AutoComplete就可以是一个Behavior,它包括对TextBox输入事件的相应,包括显示下拉,可能好包括通过Web Service查询可提供的选项,这些逻辑原本的耦合度不高,不应该聚合成为Control,但是它们在一个特定的交互操作中聚合在一次,因此就应该将它们定义为一个Behavior。
另外,ASP.NET Futures还提供了一种比Event更高层次的事件机制,称之为Action。我们现在能看到一些服务器端控件包含一些成对出现的数据操作时间,例如Updating/Updated、Inserting/Inserted、Deleting/Deleted,之所以要这样设计是为了向开发人员提供一个更灵活的接口,允许开发人员在特定的事件之前以及之后进行自己的逻辑调用。例如Update操作吧,其实这对于数据控件来说是一个事件,然而对外暴露则成了Updating/Updated两个事件,这就增加了事件的数量。Action的引入正是为了解决这个问题,在向一个Action添加事件处理函数时就可以声明这个函数是在Action前调用还是在Action后调用。有些Action是仅被执行一次的,只有已执行和未执行这两种状态,添加事件处理函数时可以声明如果Action被执行过了事件马上被触发。Action机制的引入都大大简化了复杂对象的事件模型。
ASP.NET Futures值得一提的强大功能还有Binding。这名字听起来与服务器端的数据绑定有点关系,实际上也正是这样。 Binding可以绑定任意两个对象的属性(注意是ASP.NET AJAX/Futures引入的属性概念而不是成员变量),这种绑定可以单向的也可以是双向的,而且绑定支持Transform。什么是Transform呢?例如你提供一个下拉列表提供用户选择罗马数字的i、ii、iii、iv、v、vi……然后这个下拉选择的值要绑定到一个对象的属性上,该属性是一个Number,那么你就可以设计一个Transform将String的罗马数字和它实际代表的Number值对应起来,之后Binding就能自动完成这个绑定,无论何时你访问此对象属性,你得到的都是用户选择的罗马数字对应的数值。
最后需要了解的是,ASP.NET Futures还引入了Drag and Drop与Animation的支持。前者为页面上的拖放操作提供了一个低层框架;后者类似于基于Prototype的Scriptaculous库的Effect,提供了丰富的HTML元素动画效果。
第1部分到这里就结束了,我们通过这部分内容了解了以客户端为中心的3种Ajax应用模型,知道了ASP.NET Futures为开发提供的底层框架。在之后的文章当中,我们将来探讨如何使用ASP.NET Futures进行实际的开发,并且看看它有多大的潜力以适应未来的Ajax网站发展趋势