ActionView 中的 Yield 魔法是如何发挥作用的?
我是查看 content_for 的工作原理并观察 capture_erb_with_buffer
中的 block.call
方法。它显然神奇地写入了缓冲区变量,然后该变量被修剪。但是,我认为这已被弃用,您现在可以调用 <%=yield :tag%>
。这是如何运作的?如果我从 ERB 模板调用yield,那么yield会到哪里?
一个简单的代码示例来说明这一点将不胜感激。
I was looking at how content_for works and observed the block.call
in the capture_erb_with_buffer
method. It apparently magically writes to the buffer variable which is then pruned. However, this I believe is deprecated and you can just call <%=yield :tag%>
now. How does this work? If I call yield from an ERB template where does that yield to?
A simple code sample to illustrate the point would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不确定
yield
在 ERB 级别上如何发挥作用,但我确实知道它在应用于布局时如何工作。下面是一个示例布局.html.erb 文件:
我定义了 4 个产量(:head、:menu、:footer 和 default)和一个实例变量@title。
现在控制器操作可以渲染插入这些点的视图。请注意,视图在布局之前渲染,因此我可以在视图中定义像 @title 这样的变量,并在布局中定义它。
示例视图:
关于页面
编辑页面
您可以混合和匹配要放入数据的产量,
content_for :something
中发生的内容将插入到匹配的yield :something
中> 在布局文件中。它甚至适用于部分,部分可以插入自己的 content_for :something 块,该块将与任何其他 content_for 调用一起添加。
I'm not certain how
yield
functions on the ERB level, but I do know how it works when applied to layouts.Heres a sample layout.html.erb file:
I have defined 4 yields(:head, :menu, :footer, and default) and an instance variable @title.
Now controller actions can render views that slot into these spots. Note that the view renders before the layout, so I can define a variable like @title in a view and have it defined in the layout.
Sample views:
An About page
An Edit page
You can mix and match what yields you want to put data in, and what occurs in the
content_for :something
will be inserted in the matchingyield :something
in the layout file.It even works for partials, a partial can insert its own content_for :something block which will get added with any other content_for calls.
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
do |*names|... end
块是接收yield
的块。您会注意到@content_for_#{names.first}
与content_for
流程中设置的变量相匹配。它是从 #render 中的 AV::TemplateHandlers::Compilable 调用的,我也会假设其他地方。
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
This little tiny method called
execute
inActionView::Base
explains it all.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
The
do |*names|... end
block is the one receiving theyield
. You'll notice that the@content_for_#{names.first}
matches up with the variable being set in thecontent_for
process.It's called from AV::TemplateHandlers::Compilable in #render, and I would assume other places as well.
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
简单地说:
在方法中调用yield会执行通过块传递给该方法的代码。
例如,
这 5 行将在屏幕上生成以下输出,
请参阅以下页面,了解有关 Ruby 中的产量的精彩讨论: 红宝石产量
Simply:
calling yield in a method executes code that was passed to the method via a block.
For instance
these 5 lines will produce the following output to the screen
See the following page for a nice discussion of yield in Ruby: Ruby Yield