本文將討論RoR中提供的基礎服務之一:動作視圖。動作視圖可以使你更快速地將數據展現給用戶。在 本文中將介紹一些動作視圖的服務,並且將舉一個例子來說明如何使用動作視圖。
在MVC模式中的V,即視圖(View),它的作用是將數據以用戶所需要的形式展現出來,和傳統的模式不 同的是,視圖在展現數據時可以省去許多不必要的細節。也就是說,任何基於MVC模式的框架(framework) 都應該提供更容易的方法提取和顯示需要的數據。RoR就是這樣的框架。它將動作視圖作為其核心組件之 一。
在本文中,將主要討論動作視圖的基礎服務。第一部分介紹了和動作視圖相關的服務。在第二和第三 部分討論動作視圖的一些基本功能,在最後一部分,將給出一個實例來說明如何使用動作視圖。
動作視圖的服務
視圖的功能就是向用戶展現數據。下面列舉了動作視圖中的主要服務:
·模板
·布局
·分頁
當然,在動作視圖中還在很多的服務,但上面的三個服務在動作視圖中是最重要的。
模板
所謂模板,就是在一個文件中預定義了一些共用的資源,應用程序通過使用這些共用的資源,可以簡 化應用程序的開發過程,從而達到重用的目的。在動作視圖中的模板所包含的資源主要就是布局信息、一 些數據所存放的路徑等。在動作視圖中的模板很多,如HTML格式的登錄模板、以及Email模版等。
布局
從軟件(包括Web和桌面程序)上來說,布局就是將GUI中的控件進行組織和安排,也就是說布局控制 著GUI控件(如按鈕、文本框等)如何被放置在界面上。例如,布局可通過垂直等間距方式將要排列的控 件按垂直方向等間距進行排列。
分頁
分頁的作用就是將大量的數據分批地顯示在頁面上,可通過"上一頁"和"下一頁"進行頁間的切換。分 頁有些象用打印機打一個大的文檔,一張紙打不下,就將數據分成多張紙來打。雖然將分頁這種顯示數據 的方式應用到程序中可以解決大數據量顯示的問題,但這同時又會帶來另外一個問題,那就是如果對數據 進行導航,也就是翻頁問題。
除了以上提到的服務外,在動作視圖中還有其它的服務,如格式化助手等。但是上面所介紹的三個服 務是動作視圖中最重要的。在下一部分,我們將討論如何使用這些服務。
模板和格式化助手
動作視圖為我們提供了很多建立動態視圖的服務。下面是動作視圖提供的主要的服務:
·模版
·格式化助手
·分頁
·布局
上面的4種服務,除了格式化助手外,其它三個服務都已經在前面介紹過了。
模板
就象以前討論的一樣,在模板中包含了一些代碼、標記、簡單文本或它們的組合。在其中的代碼可以 通過Controller中的訪問信息提供動態的內容。代碼通過執行環境訪問信息。這個環境為代碼提供了以下 的信息:
1. Controller的實例變量,通過這些變量可以將數據從Controller傳給模板。
2. 作為存取器的Controller對象。這些對象包括對象頭、參數、請求、響應和會話。
3. 當前正在使用的Controller對象。模板代碼可以從這個Controller對象中調用它的public方法。
在RoR中的模板是RHTML文件。RHTML文件有些類似於JSP文件,在RHTML文件中有靜態的HTML,也有動態 的內容。動態的內容可以由內嵌的代碼生成技術產生,也可以用手工編寫。如以下的RHTML文件顯示了當 前的日期和時間:
<h1>大家好!</h1> <p> <b> 當前日間: <%= Time.now %> </b> </p>
和JSP類似,在RHTML中有兩種寫動態代碼的方法,一種是將代碼寫到<%= … %>中,另外一種是將代 碼寫在<% … %>中。在<%= … %>中的Ruby語句只是當作一個值返回,如果其中含有多條語句,則返 回最後一條語句的值。而將代碼放到<% … %>中,則按著正常的程序邏輯執行。雖然RHTML中可以執行 Ruby語句,但最好不要將商業邏輯代碼寫在RHTML中。代碼的執行原理可看下面的例子。
如果有以下代碼:
<% 5.times do %> <5> <% end %>
在執行RHTML時,將上述代碼轉換為Ruby語句:
5.times do puts "<5>" end
格式化助手
視圖的一個重要功能就是可以將從Controller傳過來的數據進行格式化,以便用戶更容易理解這些數 據。RoR提供的格式化助手就是用來完成這個功能的。格式化助手主要可以格式化三類信息:數字、日期 和文本。下面將討論如何使用格式化助手對這些信息進行格式化。
數字和日期格式化
格式化助手可以進行多種的轉換工作,如將本地時間轉換成另外一種形式,將數字轉換成貨幣類型、 百分比或電話號,下面是一些轉換的例子: <%= distance_of_time_in_words(Time.now, Time.local (2006, 11, 1)) %>
將得到4或其它的數字(根據你運行它的日期不同而不同)
<%= distance_of_time_in_words(Time.now, Time.now + 40, false) %>
將得到1分鐘(40表示秒)
<%= number_to_currency(99.99) %>
將得到$99.99
<%= number_to_percentage(66.6666) %>
將得到 66.667%
<%= number_to_percentage(66.66666, :precision => 1) %>
將得到 66.7%
<%= number_to_phone(1125551212) %>
將這個數字轉換為 112-555-1212
格式化文本
同樣,格式化助手也可以格式化文本。格式化操作包括截取字符串,加亮顯示字符串中的子字符串, 甚至可以將一個單詞轉換成復數。下面是一些字符串的例子:
替換字符串的子串
<%= excerpt(@str, "you", 8) %>
如果@str中的字符串是 "I love …",那麼就應該返回"I love you"
<%= highlight(@str, "love") %>
如果@str中的字符串是"I love you."
那應該顯示:
I <strong class="highlight">love</strong> you.
在字符串轉換中,最有意思轉換可能就是將英文單詞的單數形式轉換成復數形式(你可以用這個功能 查一下單詞的復數形式是什麼)。
<%= pluralize(2, "person") %>
顯示 2 people.
分頁
在第一部分我介紹了分頁的概念。在這部分我將討論如何通過RoR使分頁變得更容易。RoR通過控制層 和視圖層實現分頁。在控制層,RoR的分頁系統控制從數據庫中得到的記錄。在視圖層顯示從控制層得到 的數據,以及用於分頁顯示的導航條。下面的例子描述了將users表分頁顯示的過程:
控制層的實現:
在控制層,分頁必須按如下代碼實現:
def user_list @user_pages, @users = paginate(:users, :order_by => 'name') end
以上代碼通過paginate方法設置的分頁器。這個方法有兩個參數,第一個參數是要讀取數據的表的名 子,第二個參數是在取數據時要排序的字段。這個方法返回兩個對象,第一個對象@user_pages是分頁器 對象, 第二個對象 @users 是每一頁的記錄數。其中@users用來向視圖提供要顯示的數據。 而 @user_pages負責從表中得到數據,然後將這些數據保存在@users中。
視圖層的實現:
在視圖層的RHTML文件中,@users中的數據將被展現給用戶。pagination_links()方法可以實現導航的 功能。以下是具體的實現代碼:
<table> <tr><th>姓名</th></tr> <% for user in @users %> <tr><td><%= user.name %></td> <% end %> </table> <hr> <%= pagination_links(@user_pages) %> <hr>
看看上面的代碼是不是很簡單!!
布局
在模板中可以通過布局提供子模板。這就意味著RoR可以通過布局進行嵌套操作。布局提供了一個典型 網頁的各種組成部分,如菜單、頁腳等。下面是一個簡單的關於布局的例子。
<html> <head> <title>Form: <%= controller.action_name %></title> <%= stylesheet_link_tag 'scaffold' %> </head> <body> <%= @content_for_layout %> </body> </html>
上面的代碼是一個標准的HTML布局。最值得關注的是變量@content_for_layout。這個變量中保存了從 控制層傳過來的數據。下面代碼演示了如何從控制層傳遞數據到一個RHTML文件:
def method @msg ="測試!" end
下面是method.rhtml 文件中的代碼:
<h1><%= @msg %></h1>
變量@content_for_layout 的內容如下:
<h1>測試!</h1>
由布局生成的HTML代碼如下:
<html> <head> <title>Form: method</title> <link href="/stylesheets/scaffold.css" media="screen" rel="Stylesheet" type="text/css"/> </head> <body> <h1>測試!</h1> </body> </html>
上面的例子只是簡單地演示了如何使用布局。在RoR提供的自動生成代碼機制中的scaffold就是使用布 局來生成的輸出文件。在下一部分將給一個簡單的例子來演示如何使用模板和格式化技術。
實例
在這個例子中顯示了一些被格式化的時間、字符串和數字。
下面的代碼是控制層的代碼:
class SayController < ApplicationController def hello @time=Time.now end end
下面是視圖層(這個文件就是一個模板)的代碼:
<html> <head> <title>你好!</title> </head> <body> <h1>現在報時:<%=@time%></h1> </body> </html>
現在讓我們使用格式化功能:
class SayController < ApplicationController def hello @time=Time.now @rule="This is a rule" @price=123 end end
下面在視圖中使用格式化助手進行格式化:
<html> <head> <title>你好!</title> </head> <body> <br>現在報時:<%=@time%> <br>時間間隔:<%= distance_of_time_in_words(@time, Time.local(2006, 10, 11)) %> <br>高亮度顯示rule:<%= highlight(@rule, "rule") %> <br>將123轉換成美元: <%= number_to_currency(@price) %> </body> </html>