Ajax 和 XML: 五种常见 Ajax 模式
[indent]Asynchronous JavaScript + XML(Ajax)无疑是 2006 年最热门的技术术语,且有望在 2007 得到进一步发展。但是对您的应用程序来说它究竟有什么意义呢?Ajax 应用程序中哪一种常见架构模式应用最广泛呢?本文将介绍五种常见 Ajax 设计模式,可以使用它们作为工作的基础。[/indent]的确,Ajax 是 Web 2.0 热门术语,所有人都希望将其应用于自己的站点。但是它对我们究竟有什么意义?工程师该如何在架构的层面上将其集成到自己的站点中?在这篇文章中,我将介绍 Ajax 的基本知识,并展示一些已经成为 Web 2.0 开发最佳实践的 Ajax 设计模式。首先,[i]Ajax[/i] 仅仅是一个涉及一组技术的术语,包括 Dynamic HTML(DHTML)和 [font=NSimsun]XMLHTTPRequest[/font] 对象。DHTML 由三个元素组合而成,它们分别是超文本标记语言(Hypertext Markup Language,HTML)、JavaScript 代码和级联样式表(Cascading Style Sheet,CSS)。在 Web 页面使用 JavaScript 代码,可以动态地改变页面,包括添加、删除或更改页面内容。这就是 DHTML 的[i]动态[/i] 部分。JavaScript 代码使用 [font=NSimsun]XMLHTTPRequest[/font] 对象在加载页面后向服务器请求数据。
这两种元素的组合 —— 从服务器动态请求数据然后使用这些数据更改页面 —— 就是 [i]Ajax[/i] 的本质,也是 Web 2.0 站点的动态特性。
但这并没有真正告诉您如何实际应用这些特性以及如何在站点中使用它们。因此,需要一组简单的[i]设计模式[/i]。 如果您对这个术语感到陌生,本文推介了一本非常优秀的同名书籍(参见 [url=http://www.ibm.com/developerworks/cn/xml/x-ajaxxml2/#resources][color=#5c81a7]参考资料[/color][/url])。这本书针对工程师经常面对的任务提供了一组实现模式。它不仅提供了设计系统的最佳实践,还介绍了工程师谈论代码时用到的术语。
本文介绍了五种常见 Ajax 设计模式。它们在使用 HTML、XML 和 JavaScript 代码从服务器获取数据方面有所不同。我先介绍最简单的模式,它将使用来自服务器的新 HTML 页面来更新页面。
模式 1. 替换 HTML 片段
最常见的 Ajax 任务也许就是向服务器请求更新的 HTML 并使用它更新部分页面。可能需要周期性地完成这一任务 —— 比如,更新股市报价。也可能要按需更新 —— 比如,对搜索请求进行响应。清单 1 中的代码从服务器请求一个页面然后将内容放入页面主体的 <div> 标记中。
[b]清单 1. Pat1_replace_div.html[/b][code]<html>
<script>
var req = null;
function processReqChange() {
if (req.readyState == 4 && req.status == 200 ) {
var dobj = document.getElementById( 'htmlDiv' );
dobj.innerHTML = req.responseText;
}
}
function loadUrl( url ) {
if(window.XMLHttpRequest) {
try { req = new XMLHttpRequest();
} catch(e) { req = false; }
} else if(window.ActiveXObject) {
try { req = new ActiveXObject('Msxml2.XMLHTTP');
} catch(e) {
try { req = new ActiveXObject('Microsoft.XMLHTTP');
} catch(e) { req = false; }
} }
if(req) {
req.onreadystatechange = processReqChange;
req.open('GET', url, true);
req.send('');
}
}
var url = window.location.toString();
url = url.replace( /pat1_replace_div.html/, 'pat1_content.html' );
loadUrl( url );
</script>
<body>
Dynamic content is shown between here:
<div id="htmlDiv" style="border:1px solid black;padding:10px;">
</div>
And here.
</body>
</html>[/code] [b][color=#000000]图 1. 替换了 <div> 标记的页面[/color][/b]
[img=385,296]http://www.ibm.com/developerworks/cn/xml/x-ajaxxml2/pat1_replace_div_400_312.jpg[/img]
现在回到 [url=http://www.ibm.com/developerworks/cn/xml/x-ajaxxml2/#list1][color=#5c81a7]清单 1[/color][/url] 中的代码,来观察一些内容。第一个要注意的是 [font=NSimsun]loadUrl()[/font] 函数,它从服务器请求一个 URL。该函数使用 [font=NSimsun]XMLHTTPRequest[/font] 对象向服务器请求新内容。它还指定了一个回调函数 —— 本例中,是 [font=NSimsun]processReqChange[/font] —— 当浏览器收到内容时将调用它。
[font=NSimsun]processReqChange[/font] 函数将查看对象以确定请求是否完成。如果是的话,该函数将页面 [font=NSimsun]<div>[/font] 标记的 [font=NSimsun]innerHTML[/font] 设置为响应的文本。
将 [font=NSimsun]<div>[/font] 标记作为一个动态内容的占位符,这是 Ajax 代码的主要组成部分。这些标记没有可见的表示形式(除非添加边框,像我这样做),但它们很好地标记了内容的放置位置。工程师还使用 [font=NSimsun]<span>[/font] 标记用于可代替的片段,稍后我将对其进行演示。[font=NSimsun]<div>[/font] 和 [font=NSimsun]<span>[/font] 标记的不同之处是前者加入了一个断行符(如一个段落),而后者使用边线勾画出一节内联文本。
暂时回到 [font=NSimsun]processReqChange[/font] 函数,该函数对 [font=NSimsun]status[/font] 和 [font=NSimsun]readyState[/font] 的值进行检查非常重要。有些浏览器可能只在请求完成时才调用这个函数,而也有些浏览器会不断回调该函数从而告诉代码请求依然在运行。
清单 3. Pat1_tabs.html
[code]var req = null;function processReqChange() {
if (req.readyState == 4 && req.status == 200 ) {
var dobj = document.getElementById( 'tabDiv' );
dobj.innerHTML = req.responseText;
}
}
function loadUrl( tab ) {
var url = window.location.toString();
url = url.replace( /pat1_tabs.html/, tab );
...
}
function tab1() { loadUrl( 'pat1_tab1_content.html' ); }
function tab2() { loadUrl( 'pat1_tab2_content.html' ); }
tab1();
Tab 1
Tab 2[/code]
页:
[1]