代码之家  ›  专栏  ›  技术社区  ›  Vagmi Mudumbai

在ActionView中,收益魔法是如何工作的?

  •  3
  • Vagmi Mudumbai  · 技术社区  · 16 年前

    我是 looking at 内容是如何工作和观察 block.call 在 capture_erb_with_buffer 方法。显然,它神奇地写入缓冲区变量,然后将其删减。不过,我认为这是不赞成的,你可以打电话给 <%=yield :tag%> 现在。这是怎么工作的?如果我从一个erb模板调用yield,它向何处屈服?

    一个简单的代码示例来说明这一点将是非常感谢的。

    3 回复  |  直到 16 年前
        1
  •  2
  •   Tim Snowhite    16 年前

    这个小小的方法叫做 execute 在里面 ActionView::Base 解释一切。 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::compileable in 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

        2
  •  4
  •   Tilendor    16 年前

    我不确定如何 yield 在erb级别上的函数,但是我知道当应用到布局时它是如何工作的。

    下面是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个结果(:head、:menu、:footer和default)和一个实例变量@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 在布局文件中。

    它甚至可以用于partial,partial可以插入自己的content_for:something块,它将与任何其他content_for调用一起添加。

        3
  •  -1
  •   Patrick Klingemann    16 年前

    简单地说:

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

    例如

    def my_method
      yield
    end
    
    my_method { puts "Hello" }
    my_method { puts "World" }
    

    这5行将产生以下输出到屏幕

    Hello
    World
    

    有关ruby中的产量的详细讨论,请参见下页: Ruby Yield

    推荐文章