//本文是高手Nio的的文章,發表在在PHP&More第六期上,歡迎大家下載PHP&More Vol 6
AJAX in CakePHPCake 中的 AJAX 實質
CakePHP(以下簡稱“Cake”,本文使用的版本是 0.10.7.1856 RC3)對 AJAX 的支援是建立在 prototype 與 script.aculo.us 之上的,其自身並沒有包含伺服器端、用戶端的 AJAX 實現,所以想要在 Cake 中熟練地使用 AJAX,必須首先熟悉 prototype 和 script.aculo.us,而本文的重點並不是這兩個出眾的 JavaScript 庫。說白了,Cake 實際上只是簡化了繁瑣的 AJAX JavaScript 代碼。
Cake 中的 AJAX 相關檔案
在 Cake 中,與 AJAX 相關的檔案只有兩個:
- cake/cake/libs/view/templates/layouts/ajax.thtml
- cake/cake/libs/view/helpers/ajax.php
ajax.thtml 檔案是執行 AJAX 動作之後用於輸出的布局,和一般的布局檔案不同的是它是一個空的布局視圖檔案,沒有 header/footer 等等內容。ajax.php 檔案則是用於 Cake 視圖檔案的 AJAX 輔助類 AjaxHelper,此類中包含了很多 AJAX 動作的相關方法,詳細 API 請參考 http://api.cakephp.org/class_ajax_helper.html。
除了上述的兩個檔案外,我們還需要 Prototype 的 prototype.js 和 script.aculo.us 中的 *.js 檔案,這些檔案可在官方網站上下載到,將這些 *.js 檔案放置 cake/app/webroot/js/ 目錄下即可。對於這兩個庫,本文用的版本分別是 1.4.0 和 1.5.1。
Hello, AJAX world!
現在我們使用一個簡單的樣本簡單示範一下如何在 Cake 中使用 AJAX。這個樣本將實現點選連結之後,在頁面上載入伺服器端輸出的“Hello, AJAX world!”資訊。為了簡單起見,樣本中不使用任何資料庫,也就是不用 Cake 的模型(Model),而只用控制器(Controller)和視圖(View)。首先建立一個布局視圖檔案 cake/app/views/layouts/demo.thtml,用於自訂布局以及載入需要用到的 JavaScript 檔案,此檔案內容如下:
html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” ”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>CakePHP AJAX Demo
重點在於 $javascript->link() 的那兩行,包含了需要用到的 JavaScript 檔案 prototype.js 和 scriptaculous.js,而 script.aculo.us 庫中的其他 JavaScript 檔案都由 scriptaculous.js 統一進行包含,不用我們書寫額外的代碼,如果並不想使用 script.aculo.us 的所有 js 檔案,可以使用 load 參數進行指定包含,比如我們只用到 effects.js,可以這樣(多個則用英文逗號“,”分割開):
接下來是建立一個控制器檔案 cake/app/controllers/demos_controller.php:
此控制器的重點有三個:
設定預設布局為 demo.thtml,這樣才能在 index 視圖中使用 prototype.js 等
在視圖輔助類數組 $helpers 中加上“Ajax”輔助類
對於 AJAX 動作方法 hello() 需要將其當前布局設定為“ajax”
對應於控制器中的兩個方法(Action),我們需要在 cake/app/views/demos/ 目錄下建立兩個視圖檔案:index.thtml 和 hello.thtml。
index.thtml:
Loading…
這個視圖中有三個元素:loading、view 與 AJAX 連結。初始狀態下 loading 與 view 是隱藏的(display:none),只有點擊了 AJAX 連結之後,在載入狀態中顯示 loading,載入完成之後將其隱藏,然後顯示 view,“Hello, AJAX world!”即顯示在 view 中。此視圖的重點在於 $ajax->link(),$ajax 是 AjaxHelper 的對象執行個體,link() 方法的第一個參數是連結顯示的文本,第二個參數是 Cake 的 URL,這裡的 URL 為 /demos/hello,指向了 AJAX 動作方法 hello(),此動作最終輸出視圖 hello.thtml,第三個參數為 AJAX 選項,Cake 會自動根據選項產生連結中使用到的 JavaScript 代碼。對於一個簡單的 AJAX 動作,主要就是設定三個選項:update、loading 與 complete,這幾個選項的意義在視圖代碼的注釋中都有了詳細說明。
最後就是 hello.thtml 視圖檔案了,只是一行簡單的文本:
Hello, AJAX world!
OK,通過盡量少的編碼,我們完成了這個樣本,可以通過 http://www.somesite.com/cake/demos/ 瀏覽最終效果。
Live Search
Live Search 指的是即時查詢,通常是使用者在文字框中輸入想要查詢的關鍵字,由用戶端 JavaScript 對文字框進行觀察,監測到使用者輸入之後即時提交到伺服器,並顯示伺服器返回的結果。接下來我們將使用 Cake 的 AJAX 實現 Live Search,從一個數組中擷取符合查詢關鍵字的資料,然後即時更新到頁面中。
首先修改我們的控制器 demos_controller.php,增加一個方法 search():
在 index.thtml 視圖檔案中,加入 Live Search 的表單代碼:
這裡用到了 AjaxHelper 中的另一個方法 observeField(),此方法用於觀察某個元素的資料是否發生變化,發生變化時則調用相應的 AJAX 操作。方法的第一個參數為需要觀察的元素 id,這裡是“livesearch”文字框,第二個參數為 AJAX 選項,和 link() 方法中的相似,只不過這裡的選項設定多了 url 與 frequency,url 即 Cake 的 URL,對應於控制器中的方法,frequency 則是觀察的間隔時間,單位為“秒”,即每隔多少秒查看一下對應的元素是否發生了改變。
對應於 search() 方法,建立視圖檔案 cake/app/views/demos/search.thtml:
好了,這個 Live Search 已經完成了,是不是很簡單 現在只要在文字框中輸入字元,就會在 $langs 數組中尋找,只要包含了查詢關鍵字的結果都會被返回並更新到 view 元素中。
其他應用Cake 的 AjaxHelper 中還提供了很多方法,如用於拖曳的 drag()、drop() 及 dropRemote();用於排序的 sortable();用於自動完成的 autoComplete() 等等,由於涉及到的講解篇幅比較大,暫時就不深入了,有時間的話我再一一道來。drag/drop 可以在我寫的 Cake Framework AJAX Demo 中看到線上示範,並可下載到原始碼。
一些問題Cake 目前的版本(0.10.7.1856 RC3)的一些方法還不是非常完善,對於最新版本的 script.aculo.us 庫中的一些參數還不支援,相信很快會得到更新。實際應用中可能會碰到中文亂碼的問題,那是因為 XMLHttpRequest 擷取到的資料都是以 UTF-8 編碼的,所以解決的辦法有兩個,一個是所有頁面、資料庫資料均使用 UTF-8 編碼,這樣可以省去很多麻煩,另外一個就是通過 PHP 的 iconv() 函數進行轉碼,但這需要用到 iconv 擴充,所以比較麻煩一些,而且無形中為伺服器增加了額外的負擔。
相關資源
- Prototype
- script.aculo.us
- Cake AjaxHelper Api
- Cake Framework AJAX Demo
- CakePHP Ajax Helper
- Using Ajax (and company) with Cake
- AJAX in CakePHP 樣本原始碼
from: http://www.infor96.com/~nio/ajax-in-cakephp/