ruby-----render讲解
- 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里有这样一段代码:
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选项:
1. render :nothing=>true
render的第一个参数如果是一个string或者symbol,rails则会去渲染同一个controller下的某action对应的模板,比如:
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中没必要写得这么麻烦:
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:
1. render 'products/show'
下面的代码有同样的效果,只是在Rails2.3中没必要写得这么麻烦:
1. render :template => 'products/show'
还可以渲染其它任意位置的模板文件,比如说在某种情况下,两个rails应用共享了同一个模板文件:
1. render "/u/apps/warehouse_app/current/app/views/products/show"
rails根据参数的第一个字符是否"/"来判断这是不是一个file render(怎么翻译? - -)。
下面的代码有同样的效果,只是在Rails2.3中没必要写得这么麻烦:
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模板:
render :inline => "<% products.each do |p| %><p><%= p.name %><p><% end %>"
几乎没有什么理由使用:inline这个选项,在controller逻辑中混入ERB代码违反了Rails的MVC原则并且使其它开发者难以理解你的程序逻辑。最好是用分离了"逻辑"和"表现"的erb模板来代替:inline选项。
inline rendering默认使用ERB,你也可以通过指定:type选项来强制它使用Builder:
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:
1. render :update do |page|
2. page.replace_html 'warning', "Invalid options supplied"
3. end
通过:text选项可以把一个纯文本内容发送给浏览器:
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
很简单:
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:
1. render :xml=>@product
后面的那小段英文就不多引用了,一样。
Rendering Vanilla JavaScript
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:
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:
render :layout => 'special_layout'
You can also tell Rails to render with no layout at all:
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:
render :status => 500
render :status => :forbidden
:location
引用
You can use the :location option to set the HTTP Location header:
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 %>