Как волшебство урожая работает в ActionView? - PullRequest
3 голосов
/ 13 апреля 2010

Я смотрел , как работает content_for, и наблюдал block.call в методе capture_erb_with_buffer. По-видимому, он волшебным образом записывает в буферную переменную, которая затем удаляется. Однако, я считаю, что это устарело, и вы можете просто позвонить <%=yield :tag%> сейчас. Как это работает? Если я вызываю yield из шаблона ERB, где это уступает?

Был бы очень признателен за простой пример кода для иллюстрации.

Ответы [ 3 ]

4 голосов
/ 14 апреля 2010

Я не уверен, как 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 в файле макета.

Он работает даже для частичных операций, часть может вставить свой собственный блок content_for: что-то, что будет добавлено с любыми другими вызовами content_for.

2 голосов
/ 26 апреля 2010

Этот маленький крошечный метод под названием 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 :: 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

0 голосов
/ 14 апреля 2010

Просто:

при вызове yield в методе выполняется код, который был передан методу через блок.

Например

def my_method
  yield
end

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

эти 5 строк приведут к следующему выводу на экран

Hello
World

См. Следующую страницу для хорошего обсуждения выхода в Ruby: Выход Ruby

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...