天天看點

一個經典的Rails AJAX 搜尋 排序 和分頁示例

[color=green]寫在前頭

綠色的部分是,這個介紹容易出問題部分的解釋。本來就是面向零基礎,才寫的,是以不怕麻煩和瑣碎。然而,如果你還是嫌太麻煩,或者你不希望了解細節的話。那麼,我建議你直接點選[url=http://hinder.iteye.com/topics/download/fc389e2c-e6f9-38cd-ba6f-7a76247aa0d5]這裡[/url],下載下傳ajaxtable.rar的壓縮包。在安裝ruby和rails的環境下,到解壓的目錄下,運作ruby script/server直接看效果。

壓縮包裡有paginate的plugin,資料庫也不用配置因為是檔案的。萬一你的系統不認sqlite3,請下載下傳sqlite3的rar,裡面有個gem包安裝就可以了。

希望能夠給有興趣的,或者初學者帶來幫助

[/color]

這是一個相當經典的(我認為^_^)用來展示,ajax調用排序,搜尋和分頁的示例。這個示例的特點是把過程寫的相當的啰嗦,大媽專殺。以至于非常的好了解,非常的初級,非常的好用。

[b][size=medium]任務說明簡介和重要提示[/size][/b]

在這個示例教程理,我們将要使用Rails的AJAX,來實作對結果集的如下功能:

1. 分頁

2. 排序,可以對結果集的任何一個屬性進行ajax排序。

3. 查詢,ajax檢索

線上的示例示範,請通路如下網址:(還沒有準備好...)

能夠部分重新整理的對頁面的結果集進行更新,變得越來越普遍。對于Rails來說,天生的和ajax有着完美的支援。是以,對這項功能的實作相當容易。

示例中的代碼, 很大部分來源于Rails Wiki的官方說明。特别是How to make a real-time search box with the Ajax helpers 和 How to paginate with Ajax.我隻是把這些代碼攢到了一起,不能用的時候,稍微改了一下變量名。以便看起來更不像抄襲。

注意啦,很重要:

我既不是Rails高手,也不是AJAX大拿。在這兩個領域裡,我都是擁有長期經驗的菜鳥。是以這個示例是面對初學者和大媽們的。你會看到簡介的代碼,詳盡的解釋,但是缺乏高效規範。幸好,雖然,我的母語是漢語,但是難免還是有錯誤。

任何時候,請到我的部落格告訴我。

[b]應用安裝和配置[/b]

在這個示例中,我們假設已經安裝了目前的Rails環境(至少高于2.0)和支援資料庫。在我們這裡用Sqlite,當然你也可以很容易的使用其他的資料庫代替。

架構生成:

我們要在目錄下生成“skeleton”先:

在rails 2.0以後,分頁的功能已經從Rails core中分離出來,成為一個獨立的plugin叫作classic pagination。很不幸的很多開發者,認為will_paginate是更加流行的分頁插件。但是,我并沒有使用will_paginate整合我的示例。是以,我們還是首先,使用下面的指令安裝classic pagination plugin

[color=green]這裡如果不能安裝,請直接下載下傳附件classic_pagination.rar解壓縮放到verdor\plugin目錄,就不用安裝分頁插件了。[/color]

鑒于,我們搭建的是一個非常基礎的應用,是以,我們隻有一個用來存儲結果集的model和controller。我們将使用如下Rails的scripts生成

[b]資料庫準備:[/b]

簡單起見,我們選擇sqlite做存儲。這将意味着我們将描述檔案放到Rails中,并且用它生成資料庫。

更新資料庫配置檔案:config/database.yml如下:

然後,我們将使用如下Rails migration 工具建立資料庫如下:

這條語句将生成類似db/migrate/20090303130724_database_creation.rb的檔案。

[color=green]修改這個檔案,重新定義資料庫表結構[/color]

然後,運作如下:

[color=green]這裡如果,出現不能安裝錯誤請下載下傳附件sqlite3.rar,并放到ruby\bin目錄下,執行[/color]

用以建立表結構。接下來将加載資料

在db目錄下應該有一個development.db的檔案,這個檔案就是存儲sqlite資料。

你可以用如下的方法插入資料建立db/dump.sql如下:

運作:

[color=green]注意:

1.如果運作這個指令的時候,提示找不到sqlite3,請下載下傳sqlite3的附件,放到ruby\bin\下,并且運作時,請指明路徑

2.如果你使用的資料庫是mysql請自己修改,insertinto的語句格式如下 INSERT INTO items VALUES (1, 'hoe', 3, 10);[/color]那麼,到現在為止,我們準備好了資料庫和用到的檔案

[b]建立model[/b]

就像你應該知道的,Rails程式通常會分為三層。實際上我們已經建立了/models/item.rb檔案。并且我們并不需要更改。

那麼,看起來,我們的第一步編碼工作還不算太困難。

[b]建立view[/b]

我們應用将被分成兩個部分,一個layout 另外一部分是view和partial。

Layout

Layout是頁面模闆用來容納不同的幾個views。Layout包含一些不變的元素例如:html的header和footer資訊,導航和設計元素等。當然,這些功能完全沒有能夠在我們的示例中展現。因為,我們隻有一個頁面,

那麼layout應該在app/views/layouts/item.rhtml,其中代碼如下:

在這段代碼中,值得注意的是javascript_include_tag 将加載對應的javascript庫,以便Rails可以得到AJAX功能支援。

@content_for_layout 部分,将會被生成的内容代替。

[b] view部分[/b]

view将會把controller的結果展示。邏輯部分在一節詳述。根據Rails配置原則,我們view将對應item controller的listaction是以我們的view在

app/views/item/list.rhtml.

該檔案的内容如下:

開始部分并沒有什麼複雜的,首先,是一段大媽專用的說明和一個檢索輸入框用以Filter。

然後,我們有一個id是spinner的隐藏image元素。這個image是用來AJAX有延遲調用的時候顯示的(flash加載的滾動條)。當ajax的異步調用完成,可以顯示資料時,這個image将再次隐藏。你可以從如下的網站得到更多的類似圖檔:

http://mentalized.net/activity-indicators/

[color=green]從上面的網站中下載下傳一個gif,并重命名為spinner.gif放到public/images下。[/color]

在接下來的observe_field代碼部分是最常用的AJAX代碼。它的含義大概是定期檢查指定區域的内容,并且當内容有變化的時候響應。

其中,使用到的變量有如下含義:

update 參數描述将要更新的<div>或<span>的id

url 該參數,指定響應和處理action。就是定期觸發什麼方法。

with 該參數,用以給url中指定的action,傳遞參數。在這裡我們将會把observed field的檢索資料傳給list action

before 該方法用以指定,當AJAX的異步調用進行中将怎麼執行。

sucess 當ajax的異步調用成功後,執行什麼操作。

實際的操作流程相當簡單,當使用者在queryfield的檢索框内輸入要查詢的東西,observerd 就會檢測到監視區域的内容變化,然後,生成AJAX的請求,異步調用通過url和with的發送給伺服器。注意這時頁面是整體和局部都不重新整理的。當請求發送的時候,before定義的操作将被執行。在我們的示例中是顯示spinner圖檔。當請求有回複的時候,sucess的操作将被執行,在我們這裡是隐藏圖檔。

實際上,observe_field方面發送的請求參數如下:

我們花時間來看,沒一個參數選項的具體含義,是因為我們很快會再用到這些幾乎每一種ajax調用都要用到的參數,

建立controller

我們的controller應該可以根據請求類别和參數的不同處理多種的請求。

Item contoller将會非常簡單,我們隻實作一個list的action。其他CRUD(建立、讀取、更新、删除)方法将不在本示例中展示

那麼,controller的内容如下:

[color=green]修改\ajaxtable\app\controllers\item_controller.rb[/color]

本段代碼的簡單說明如下:

controller的唯一一個方法,用于處理各種不同請求。其中,items_per_page 參數用以定義每頁顯示數量。sort參數取決于同名的傳入參數。出于安全考慮以此代替真正的字段名。sort 中的reverse參數用于保證再次點選的時候可以依序排列。

conditions 參數用來指定從query請求參數提供的檢索條件。這個參數是類似SQL樣式。

然後,我們指定@total變量用來存儲符合conditions條件的記錄個數。

最終,我們調用Rails的分頁機制。我們需要關聯分頁到資料庫:item,和一個可排序字段,一個符合conditions的檢索條件,和一個每頁的顯示個數。分頁機制就會傳回,一個@items_pages 的對象用以分頁顯示。

Rails和Ajax使用XmlHttpRequest,這不同與普通的GET和POST請求。XHR的請求由javascript通過背景的Http調用觸發,請求一個部分的Xhtml代碼片段來更新部分的浏覽器顯示。這樣的好處是不用重新加載整個頁面。使用者的使用體驗,會是以變快。

那麼接下來呢?

[b]建立partial[/b]

partial是用來顯示部分的頁面。partial的設計初衷是為了複用,滿足DRY(Don‘t Repeat Yoursel)的原則,當然,這裡對于AJAX也非常有用。

這裡我們使用partial更新部分頁面,正好滿足AJAX部分更新的要求。

Partial檔案的名字總是下劃線開頭。我們的partialapp/views/item/_items_list.rhtml,内容如下

[b]分頁的helpers檔案[/b]

在開始的時候,我們有一個符合條件的記錄數和設定的每頁顯示記錄數的判斷。如果,符合條件的記錄數小于每頁可以顯示的記錄數,則不用分頁。

相反,我們就需要要顯示分頁資訊,雖然,Rails已經有了處理和顯示的機制。可是我們希望能夠實作ajax分頁。那麼我們需要建立pagination的helpers。

helper方法是用來幫助生成和顯示view的。目的是為了将顯示和邏輯分離,當然一定程度的複用和代碼重構。

我們的helper檔案在app/helpers/item_helper.rb. 我們的view可以讀取這個檔案的任何一個方法。但是,如果我們如果,希望應用中的任何view都可以使用這個檔案的方法,那麼我們就需要把代碼放到application_helper.rb.

内容如下:

我們定義隻有一個window_size的page_options的hash。這個參數辨別目前頁旁邊的可以顯示的頁,如下如果window_size=1那麼就會顯示如下:

1 ... 5 6 7 ... 13

如果 window_size=2則顯示

1 ... 4 5 6 7 8 ... 13

這樣,我們就可以通過pagination_links得到對應的xhtml分頁後的xhtml通過以上的連接配接。這的确可以用,然而,我們希望能夠異步調用,實作AJAX的分頁,是以我們重寫pagination_links_each 方法

pagination_links_each 方法參數分析:

option和類似之前我們observe_field的參數,新的部分是params.merge,表示我們通過連接配接把将目前的請求參數代替之前的狀态。

html_options是用來定義沒有AJAX支援下的分頁顯示。以便分頁機制在沒有javascript支援下也可以用。

下面是實際的有兩個頁面市,第一個頁面顯示時的生成代碼

sorting helpers

繼續添加helpers

sort_td_class_helper代碼如下:

作用是添加一個class="sortup"用以支援逆序排列

sort_link_helper.

這個helper是上面pagination_links_remote的縮小版,它有兩個參數:

text 用于顯示字段的頭和排序連接配接

param 和字段關聯的請求參數

本段代碼首先定義一個變量key用于保持param傳遞過來的參數。_reverse用于表示param是否正在排序中的參數。也就是說實作,第二次點選逆序。

接下來的代碼定義了link_to_remote方法需要的參數,和paginateion_links_remote非常類似

option是哈希表,詳情見上

html_options 也還是為了javascripte不支援下的功能實作。

下面是sort_link_helper以Quantity" 和 "qty" 作為 text 和 param 參數傳回值的顯示表格

最後,在用patial顯示table的時候,如果希望能夠,一行一個顔色,我們需要加入一個cycle的rails方法,來自動增加奇數和偶數的樣式方法。

[b]最後了[/b]

我們已經或多或少的看了,在這個示範中用到的所有技術細節。在這個過程的最後,通過如下url享用你的勞動成果。

如果,這個文檔對你有那麼半點幫助,我的時間就值得欣慰了。我再重複一下,有什麼問題請在我的部落格回報。

謝謝

繼續閱讀