Rendering in Rails

       

   

Ruby rails頁面跳轉代碼如下:

1.render(:text => string)   
2.render(:inline => string, 
  [:type => "rhtml"|"rxml"])   
3.render(:action => action_name)   
4.render(:file => path, 
  [:use_full_path => true|false])   
5.render(:template => name)   
6.render(:partial => name)   
7.render(:nothing=>true)   
8.render()  
第1行:直接渲染出文本 
第2行:把傳入的string渲染成模板(rhtml或者rxml) 
第3行:直接調用某個action的模板,相當於forward到一個view 
第4行:使用某個模板文件render, 當use_full_path參數爲true時可以傳入相對路徑 
第5行:使用模板名render,e.x.: render(:template => "blog/short_list") 
第6行:以局部模板渲染 
第7行:什麼也不輸出,包括layout 
第8行:默認的的render, 相當於render(:action => self) 

如果action中沒有調用render、redirect_to、head和method_missing方法中的任何一個,rails默認會去渲染和當前action名字相對應的那個模板。redirect_to和render的區別:render渲染用戶指定的模板作爲響應 ,redirect_to會結束當前響應,並告訴瀏覽器請求一個新的url 。

比如一個BooksController裏有這樣一段代碼:

           Ruby代碼           

                   1. def show 

                   2. @book = Book.find(params[:id])  

                   3. end  

           rails將會在執行完show方法後渲染 app/views/books/show.html.erb 模板。

           引用

                  If you want to see the exact results of a call to render without needing to inspect it in a browser, you can call render_to_string. This method takes exactly the same options as render, but it returns a string instead of sending a response back to the browser.

           如果你希望給瀏覽器發送一個空的響應信息,可以使用:nothing選項

           Ruby代碼                     

                  1. render :nothing=>true  

           render的第一個參數如果是一個string或者symbol,rails則會去渲染同一個controller下的某action對應的模板,比如:

           Ruby代碼               

                   1. def update 

                   2.       @book = Book.find(params[:id]) 

                   3.       if @book.update_attributes(params[:book]) 

                   4.             redirect_to(@book) 

                   5.       else

                   6.             render "edit" #OR render :edit

                   7.       end

                   8. end  

           上面的代碼在@book.update_attributes方法返回false時,將會去渲染這個controller中edit這個action對應的模板。下面的代碼有同樣的效果,只是在Rails2.3中沒必要寫得這麼麻煩:

           Ruby代碼                   

                   1. def update 

                   2.       @book = Book.find(params[:id]) 

                   3.       if @book.update_attributes(params[:book]) 

                   4.             redirect_to(@book) 

                   5.       else

                   6.             render :action=>'edit' 

                   7.       end

                   8. end

           如果要渲染的是另一個controller的模板,可以在render方法的參數中直接指定那個模板的路徑(相對於app/views的相對路徑),比如說你要在app/controllers/admin下的AdminProductsController中渲染app/views/products/show.html.erb模板,可以這樣調用render:

           Ruby代碼                    

                   1. render 'products/show'  

           下面的代碼有同樣的效果,只是在Rails2.3中沒必要寫得這麼麻煩:

           Ruby代碼  

                   1. render :template => 'products/show'

           還可以渲染其它任意位置的模板文件,比如說在某種情況下,兩個rails應用共享了同一個模板文件: 

           Ruby代碼  

                   1. render "/u/apps/warehouse_app/current/app/views/products/show"

           rails根據參數的第一個字符是否"/"來判斷這是不是一個file render(怎麼翻譯? - -)。 

           下面的代碼有同樣的效果,只是在Rails2.3中沒必要寫得這麼麻煩: 

           Ruby代碼  

                   1. render :file => "/u/apps/warehouse_app/current/app/views/products/show"

           默認的,file render不使用當前的layout,如果你打算讓它使用當前的layout,必須指定:layout=>true。

           注意:如果你的rails運行在Microsoft Windows上,則必須使用:file選項來渲染文件,因爲Windows文件名的格式和Unix不一樣

           :inline選項可以讓render方法渲染一個字符串,而不是一個erb模板:

           Ruby代碼  

                   render :inline => "<% products.each do |p| %><p><%= p.name %><p><% end %>"

           幾乎沒有什麼理由使用:inline這個選項,在controller邏輯中混入ERB代碼違反了Rails的MVC原則並且使其它開發者難以理解你的程序邏輯。最好是用分離了"邏輯"和"表現"的erb模板來代替:inline選項。

           inline rendering默認使用ERB,你也可以通過指定:type選項來強制它使用Builder: 

           Ruby代碼  

                   1. render :inline => "xml.p {'Horrid coding practice!'}", :type => :builder  

           引用

                  Using render with :update

                  You can also render javascript-based page updates inline using the :update option to render:

           Ruby代碼                    

                  1. render :update do |page|  

                  2.        page.replace_html 'warning', "Invalid options supplied"

                  3. end

           通過:text選項可以把一個純文本內容發送給瀏覽器:

           Ruby代碼  

                  1. render :text =>'hello'

           引用

                  Rendering pure text is most useful when you’re responding to AJAX or web service requests that are expecting something other than proper HTML.

           和file render一樣,默認的,:text選項不使用當前的layout,如果你打算讓它使用當前的layout,必須指定:layout=>true。

           渲染json

                  很簡單:

                  Ruby代碼  

                  1. render :json=>@product

                  引用

                  You don’t need to call to_json on the object that you want to render. If you use the :json option, render will automatically call to_json for you.

           渲染xml

                  同json:

                  Ruby代碼  

                  1. render :xml=>@product

                  後面的那小段英文就不多引用了,一樣。

           Rendering Vanilla JavaScript

                  Ruby代碼  

                  render :js => "alert('Hello Rails');"

           Options for render

                  render方法還接受4個選項:

                  :content_type 

                  :layout 

                  :status 

                  :location

                  :content_type

                  引用

                         By default, Rails will serve the results of a rendering operation with the MIME content-type of text/html (or application/json if you use the :json option, or application/xml for the : xml option.). There are times when you might like to change this, and you can do so by setting the :content_type option: 

                  Ruby代碼  

                          render :file => filename, :content_type => 'application/rss'

                  :layout

                  引用

                          You can use the :layout option to tell Rails to use a specific file as the layout for the current action:

                  Ruby代碼  

                          render :layout => 'special_layout'

                          You can also tell Rails to render with no layout at all:

                  Ruby代碼  

                          render :layout => false

                  :status

                  引用

                         Rails will automatically generate a response with the correct HTML status code (in most cases, this is 200 OK). You can use the :status option to change this: 

                         Ruby代碼  

                         render :status => 500 

                         render :status => :forbidden

                   :location

                   引用

                          You can use the :location option to set the HTTP Location header: 

                          Ruby代碼  

                          1. render :xml => photo, :location => photo_url(photo)


          需要用這樣的形式來使用:render :partial => ‘path/filename’。應當注意的是,相應的模板(.rhtml)文件該保存爲“_”開頭的。比如我的模板文件在app/views/book /_search_form.rhtml,若在BookController的方法中調用時,直接用
render :partial => ’search_form’
若在別的控制器中,則需要
render :partial => ‘book/search_form’
rails中的redirect 和 render區別
Rails裏

1. render 和 redirect 只能用一個
2. render 可以翻譯成提交,一般的電腦語言翻譯成渲染,Rails裏render可以自動方式和手動兩種
3. 動作控制器通過render方法發送內容給用戶,大多數都是提交一個“模板”。視圖可以看懂erb的模板,顯示出@變量(實例變量)----這種render提交和渲染(把模板呈現爲用戶看到的視圖)過程是自動的,不用你命令render去執行
      簡單說就是controller中方法裏定義的@foo變量,view中rhtml可以用<%=@foo%>顯示出來
4. 動作”的結果是提交不同的“模板”時,手工使用render方法
看看書上的介紹
def search
@results =Search.find(params[:query])
case @results
when 0 then render :action=> "no_results"
when 1 then render :action=> "show"
when 2..10 then render :action=> "show_many"
end
end
5. Render的方法可以提交不同的內容
* render(:text=>string) 直接render出文本
* render(:inline=>string,[:type=>"rhtml"|"rxml"])
把傳入的string當成模板處理, 相當於rhtml的內容
* render(:action=>action_name) 直接調用某個action的模板,
相當於forward到一個view
* render(:file=>path;[:use_full_path=>true|false]) 使用某個模板文件
render, 當use_full_path打開時可以傳入相對路徑
* render(:template=>name) 使用模板名render ,
例子如下 render(:template => "blog/short_list")
# 自動使用/app/views/blog/short_list.rhtml(rxml)
* render(partial=>name) :partial
* render(:nothing=>true) 什麼也不輸出,包括layout
* render() 默認的的render, 相當於render(:action=>self)
而redirect 是引導重新定向
* redirect_to(:action=>'xxx') 使用語法和url_for一樣(底層用url_for)
* redirect_to("/localpath")
* redirect_to("http://url")
rails 之 render 介紹
1. partial
 1.1 把partial作爲view的一部分來渲染,可以調用render方法:
<%=render :partial=>"menu"%>
上面的代碼會把文件名爲_menu.html.erb的模板渲染到當前模板中。
<%= render :partial => "shared/menu" %>
渲染app/views/shared/_menu.html.erb到當前模板。
1.2 可以爲partial單獨指定layout:
<%= render :partial => "link_area", :layout => "graybar" %>
partial的layout文件名必須以下劃線開頭:_graybar.html.erb,而且必須把layout模板文件和partial放在同一個目錄下。
 2. 給partial傳遞局部變量
2.1 :locals選項用於設置partial的局部變量:
<%= render :partial => "form", :locals => { :button_label => "Create zone", :zone => @zone } %>
這樣就可以在_form.html.erb中訪問button_label和zone這兩個變量。
2.2 每個partial都有一個和partial名字相同(不帶下劃線)的局部變量,可以通過:object選項給這個變量傳遞值:
<%= render :partial => "customer", :object => @new_customer %>
這樣就可以在_customer.html.erb中訪問customer這個變量,它指向@new_customer。
當然,作爲父模板(parent)的一部分,partial可以直接訪問父模板的實例變量,例如這裏的@new_customer,但是如果這麼做的話,partial就跟父模板耦合了,變得不容易重用了。所以建議使用partial的名字來引用實例變量而不是直接訪問實例變量。
      之前版本的Rails中,如果不指定:object或者:locals選項,rails會自動在父模板中尋找與partial同名的那個實例變量作爲partial的局部變量,如:
<%= render :partial => "customer" %>
如果在_customer.html.erb中訪問customer這個變量,rails將會自動在父模板中尋找名爲@customer的實例變量。這個特性在Rails2.2中已經不建議使用了(deprecated)。Rails3.0中已經將這個特性移除了。
2.3 如果要傳遞給partial的實例變量名==partial名=model名,可以簡寫,如:
#當@customer爲Customer這個model的實例,並且partial名爲customer時
<%= render :partial => @customer %>
#相當於
<%= render :partial => "customer", :object=>@customer %>
 3. 渲染集合(Collections)
3.1 :collection選項用於指定被傳遞給partial的集合對象
假設有books這麼個集合,包含了5個Book對象,可以這樣使用:
#main.html.erb
<%= render :partial => "book", :collection => books %>
#_book.html.erb
<p><%= book.name%></p>
         這 樣,在main.html.erb中,_book.html.erb的內容會被渲染5次。這時候,partial模板中,與partial同名的那個變量 指向了:collection選項傳過來的集合中的每一項。如果你不想使用這個與partial同名的變量名,可以通過:as選項來設置你想要的變量名(:as的值只能用symbol,不能是string,否則在partial裏會得到nil值):
<%= render :partial => "product", :collection => @products, :as => :item %>
3.2  下標索引值
在 設置:collection選項的時候,rails同時提供了一個counter變量給partial模板,變量名以partial名(不帶下劃線)開 頭,以_counter結尾,並且經試驗,這個變量名不受:as選項影響(也就是說在上面的代碼中,這個變量名應該是product_counter而不 是item_counter)。其值爲collection對象的索引值(從0開始)。
3.3 :spacer_template
:spacer_template選項用於指定填充於collection每個member之間的模板:
<%= render :partial => "product", :collection => @products, :spacer_template => "product_ruler" %>
上面的代碼中,_product_ruler.html.erb的內容將被填充到每一對_product partial之間。
和:object一樣,:collection也有簡寫形式: <%= render :partial => @products %>

發佈了19 篇原創文章 · 獲贊 11 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章