一、 Ajax的簡短歷史
在短短幾個月內,Ajax從一種十分模糊稀罕的技術一下變成最熱門的東西。本文將介紹極其容易使用的Ajax支持-作為Ruby on Rails web應用程序框架的一部分實現。 本文不是一個詳細的教程,所以我假定你已經了解一點關於如何組織和構建一個Rails web應用程序的知識。
最開始出現的是萬維網。比較於桌面應用程序,web應用程序相當緩慢和沉悶。無論如何,人們都喜歡上了web應用程序,因為他們無論在什麼地方都能上網,只要身邊的計算機上安裝一個浏覽器就行。之後,微軟在Internet Explorer 5中創建了XMLHttpRequest,它使得浏覽器端JavaScript可以與web服務器在後台進行通訊而不需要浏覽器顯示一新的web頁面。這使得人們有可能開發更具有流暢性和響應性的web應用程序。Mozilla不久在它的浏覽器中也實現了XMLHttpRequest,還有Apple(Safari浏覽器)和Opera等公司。
XMLHttpRequest原先一定是Web上的一個被保持得最好的秘密。自從它在1998年初次登場,只有很少幾個站點使用它,而大多數開發者,如果他們曾經了解過它的話,也從未使用過它。Google最終改變了這一現狀-它發行了一系列的高度輪廓性的web應用程序-在XMLHttpRequest技術支持下,它們擁有平滑的新穎的UI。最具有視覺吸引力的是Google Maps,它給你產生這樣的幻想-能夠在它的很小的窗口中圍繞著一個無限大小的地圖拖動鼠標。
當Google的突出對XMLHttpRequest的使用的事實戲劇性地表明完全可以大大改進web應用程序UI效果的時候,是Jesse James Garrett的一篇論文最終給了這種技術一個可用的名字:Ajax(異步JavaScript和XML)。如果還不了解它的話,我們的整個業界至今可能還在等待之中。如今新的Ajax名字就象疾風野火迅速傳播開來。我從來沒見過如此迅速和這麼親近地采納一種新技術!
二、 傳統型Web應用程序與Ajax應用程序的對比
讓我們通過分析一個使用案例-把一個新項插入到一個列表中-來看一下一個Ajax web應用程序最本質的所在。
在例中實現了一典型用戶接口-在一個web頁面中顯示當前列表,後面跟著一個輸入字段-用戶在此可以輸入一個新項的文本。當用戶點擊一個新建項目按鈕時,應用程序實際上創鍵並把一個新項插入到列表中。
在這種情況下,一傳統型web應用程序會發送輸入字段值到服務器;然後,服務器作用於數據(通常通過更新一數據庫)並通過發送回一個新的web頁面-它顯示一個被更新後的包含該新項的列表-作為響應。這種情況占用了很多帶寬,因為大多數新的頁面內容與原先的完全一樣。這個web應用程序的性能隨著列表的增長而逐漸下降。
相反,一個Ajax web應用程序在後台發送輸入字段到服務器並且只更改當前web頁面受到影響的部分。這大大提高了用戶接口的響應能力,使它感覺起來象一個桌面應用程序。
你可以親自試驗一下這些效果。下面是一些到不同博客的鏈接,其中的一個使用Ajax來發送評價而另一個沒用。你可以在它們之間相互寄送進行實驗:
·傳統型的Web應用程序
·Ajax Web應用程序
注意,Ajax僅僅在於使用性。但是,就象任何技術一樣,你可以高效地使用它,也可能低效地使用。在展示了怎樣使用Ajax之後,我將給出一些關於何時使用Ajax的簡單建議。
三、 怎樣在Web應用程序中使用Ajax
在你的web應用程序中使用Ajax技術的較麻煩的方法是創建你自己的定制JavaScript-它直接使用XMLHttpRequest對象的API。為此,你必須處理每種浏覽器的特性。
一個較容易些的辦法是使用一個JavaScript庫-它提供了較高級的Ajax服務並且隱藏了浏覽器之間的差別。象DWR,Prototype,Sajax和Ajax.NET這樣的庫都是很好的選擇。
最容易的辦法是使用Rails中內建的Ajax工具。事實上,Rails使Ajax變得如此容易,以至於在典型情況下,使用Ajax和不用變得幾乎一樣容易。
四、 Rails是怎樣實現Ajax的
Rails擁有一個簡單的一致性模型來實現Ajax操作。
一旦浏覽器生成並顯示了起始web頁面,不同的用戶操作要求它顯示一個新的web頁面(就象任何傳統型的web應用程序)或觸發一個Ajax操作:
1. 發生一個觸發器行動。這可能是用戶點擊一個按鈕或一個超級鏈接或者用戶改變了表單中的數據或字段中的數據,或只是一個周期的觸發器(基於一個定時器)。
2. 與觸發器相聯系的數據(一個字段或一個完整的表單)經由XMLHttpRequest被異步地發送到服務器上的一個行動處理器。
3. 服務器端行動處理器基於這些數據采取一些行動(這就是為什麼稱為一個行動處理器),並且返回一個HTML片斷作為它的響應。
4. 客戶端JavaScript(由Rails自動地創建)收到該HTML片斷並且使用它更新當前HTML頁面指定的部分,經常是一個<div>標簽的內容。
一個到服務器的Ajax請求也可能返回任意的數據,但是我將僅討論一下HTML片斷。真實的美麗在於Rails使得在你的web應用程序中實現這些是多麼地容易。 五、 使用link_to_remote
Rails有若干幫助者方法以在你的視圖的模板中實現Ajax。一種最簡單且很通用的方法就是link_to_remote()。讓我們考察一個簡單的web頁面-它實現詢問時間並且有一個鏈接,用戶可以點擊這個鏈接來獲得當前的時間。該應用程序經由link_to_remote()使用Ajax以檢索時間並且顯示它於web頁面。
我的視圖模板(index.rhtml)看起來象:
上面的模板中有兩個很有意思的幫助者方法,以粗體標出。javascript_include_tag()包括了Prototype JavaScript庫。所有的Rails Ajax特性都使用這個JavaScript庫-它被包含在Rails分發包之中。
這裡的link_to_remote()調用使用了它的最簡單的形式,有3個參數:
1. 要顯示的鏈接文本-在本例中是,"點擊這裡"。
2. DOM元素的id,它包含將用行動執行結果進行替換的內容,在本例中是time_div。
3. 要調用的服務器端行動的URL-在本例中是,一個叫作say_when的行動。
這裡的索引行動處理器不做任何東西,除了讓Rails承認有一個索引行動並生成index.rhtml模板外。這個say_when行動處理器構建一個HTML片斷-它包含當前日期和時間。圖1和2顯示了在點擊"點擊這裡"鏈接前後索引頁面是怎樣顯示的。
當用戶點擊"點擊這裡"鏈接時,浏覽器構建一個XMLHttpRequest對象,並把它發送到服務器-伴隨一個將調用say_when行動處理器的URL-它返回一個包含當前時間的HTML響應片斷。客戶端JavaScript接收到該響應並且通過它來用一個time_div id替換<div>的內容。
也有可能插入這個響應,而不是代替現有內容:
請注意上面加粗的兩部分,它們定義了表單的開始和結束。因為該表單以form_remote_tag()而不是form_tag()開始,應用程序將使用XMLHttpRequest提交這個表單。form_remote_tag()中的參數看上去是:
·更新參數用於指定DOM元素的id及行動執行結果要更新的內容-在本例中是my_list。
·url參數用於指定服務器端行動-在本例中,調用一個稱為add_item的行動。
·位置參數代表插入到my_list元素頂部的返回的HTML片斷-在本例中是一個<UL>標簽
七、 使用觀察器