2010-04-13 51 views
3

我是looking at content_for的工作方式,并观察capture_erb_with_buffer方法中的block.call。它显然魔法写入缓冲区变量然后修剪。但是,我相信这已被弃用,您现在可以致电<%=yield :tag%>。这个怎么用?如果我从ERB模板中调用收益率,那么收益率是多少?ActionView中的产量魔术如何工作?

一个简单的代码示例来说明这一点将不胜感激。

回答

2

这在ActionView::Base中被称为execute的小微小方法解释了这一切。 http://google.com/codesearch/p?hl=en#m8Vht-lU3vE/vendor/rails/actionpack/lib/action_view/base.rb&q=capture_helper.rb&d=5&l=337

def execute(template) 
    send(template.method, template.locals) do |*names| 
     instance_variable_get "@content_for_#{names.first || 'layout'}" 
    end 
    end 

do |*names|... end块是一个接收yield。您会注意到@content_for_#{names.first}与在content_for过程中设置的变量相匹配。

它从AV :: TemplateHandlers :: Compilable在#render中调用,我也假设其他地方。

def render(template) 
    @view.send :execute, template 
    end 

http://google.com/codesearch/p?hl=en#m8Vht-lU3vE/vendor/rails/actionpack/lib/action_view/template_handlers/compilable.rb&q=execute&exact_package=git://github.com/payalgupta/todo-list.git&sa=N&cd=17&ct=rc&l=28

4

我不确定在ERB级别yield的功能如何,但我知道它在应用于布局时是如何工作的。

下面有一个样本layout.html.erb文件:

<html> 
    <head> 
    <title> <%= @title || 'Plain Title' %> </title> 
    <%= yield :head %> 
    </head> 
<body> 
    <div id='menu'> 
    <%= yield :menu %> 
    </div> 
    <div id='content'> 
    <%= yield %> 
    </div> 
    <div id='footer'> 
    <%= yield :footer %> 
    </div> 
</body> 

我已经定义4个产率(:头,:菜单,:页脚和默认值)和一个实例变量@title。

现在控制器操作可以呈现插入这些点的视图。请注意,该视图在布局之前呈现,因此我可以在视图中定义一个像@title这样的变量,并在布局中定义它。

样的观点: 一个关于页面

<% @title = 'About' %> 
<% content_for :menu do %> 
    <%= link_to 'Back to Home', :action => :home %> 
<% end %> 

We rock! 

<% content_for :footer do %> 
    An Illinois based company. 
<% end %> 

编辑页面

<% @title = 'Edit' %> 
<% content_for :head do %> 
    <style type='text/css'> .edit_form div {display:inline-block;} </style> 
<% end %> 

<% form_for :thing, :html => {:class => 'edit_form'} do |f| %> 
    ... 
<% end %> 

你可以混合和匹配你想要的东西产生把数据,什么发生在content_for :something会插入匹配yield :something的布局文件中。

它甚至适用于partials,partial可以插入它自己的content_for:东西块,它将被添加任何其他content_for调用。

+0

@Tilendor,很好写了+1。 – 2010-04-13 21:28:08

-1

只需:

在方法中调用yield会执行通过块传递给方法的代码。

例如

def my_method 
    yield 
end 

my_method { puts "Hello" } 
my_method { puts "World" } 

这5条线路将产生如下输出到屏幕

Hello 
World 

对产量的Ruby的一个很好的讨论,请参阅下页:Ruby Yield