Spec-Zone.ru › Ruby on Rails 4.2

класс ActionView::PartialRenderer

Родитель:
ActionView::AbstractRenderer

Частичные представления Action View

Также имеется удобный метод для рендеринга подшаблонов внутри текущего контроллера, зависящего от одного объекта (мы называем такие подшаблоны частичными представлениями). Он опирается на соглашение об именовании частичных представлений, которые должны начинаться с подчёркивания — для их разделения от обычных шаблонов, которые могут быть рендерены самостоятельно.

В шаблоне для Advertiser#account:

<%= render partial: "account" %>

Это отобразит «advertiser/_account.html.erb».

В другом шаблоне для Advertiser#buy, мы можем иметь:

<%= render partial: "account", locals: { account: @buyer } %>

<% @advertisements.each do |ad| %>
  <%= render partial: "ad", locals: { ad: ad } %>
<% end %>

Это сначала отобразит «advertiser/_account.html.erb» с @buyer, переданным в качестве локальной переменной account, а затем отобразит «advertiser/_ad.html.erb» и передаст локальную переменную ad в шаблон для отображения.

Параметры :as и :object

По умолчанию ActionView::PartialRenderer не имеет локальных переменных. Параметр :object может использоваться для передачи объекта в частичное представление. Например:

<%= render partial: "account", object: @buyer %>

передаст объект @buyer в частичное представление, доступный под локальной переменной account и эквивалентен:

<%= render partial: "account", locals: { account: @buyer } %>

С параметром :as мы можем указать другое имя для данной локальной переменной. Например, если мы хотим, чтобы это было user вместо account , мы сделаем:

<%= render partial: "account", object: @buyer, as: 'user' %>

Это эквивалентно

<%= render partial: "account", locals: { user: @buyer } %>

Отображение коллекции частичных представлений

Пример использования частичных представлений описывает распространённый шаблон, где шаблон должен перебирать массив и отображать подшаблон для каждого элемента. Этот шаблон реализован как единственный метод, принимающий массив и отображающий частичное представление с тем же именем, что и элементы, содержащиеся в нём. Таким образом, трёхстрочный пример в «Использование частичных представлений» можно переписать в одну строку:

<%= render partial: "ad", collection: @advertisements %>

Это отобразит «advertiser/_ad.html.erb» и передаст локальную переменную ad в шаблон для отображения. Объект итерации автоматически будет доступен шаблону под именем partial_name_iteration. Объект итерации знает, какой индекс имеет текущий объект в коллекции и общий размер коллекции. Объект итерации также имеет два удобных метода, first? и last?. В случае приведённого выше примера, шаблон получит ad_iteration. Для обратной совместимости параметр partial_name_counter по-прежнему присутствует и сопоставляется с методом index итерации.

Параметр :as может быть использован при отображении частичных представлений.

Вы можете указать частичное представление, которое должно быть отображено между элементами, через параметр :spacer_template . Следующий пример отобразит advertiser/_ad_divider.html.erb между каждым частичным представлением «ad»:

<%= render partial: "ad", collection: @advertisements, spacer_template: "ad_divider" %>

Если заданный :collection равен null или пуст, render вернёт null. Это позволит вам указать текст, который будет отображён вместо него, используя такой формат:

<%= render(partial: "ad", collection: @advertisements) || "There's no ad to be displayed" %>

ПРИМЕЧАНИЕ: Из-за проблем с обратной совместимостью коллекция не может быть массивом хэшей. Обычно в нём также хранятся только сущности домена, такие как Active Records.

Отображение общих частичных представлений

Два контроллера могут совместно использовать набор частичных представлений и отобразить их так:

<%= render partial: "advertisement/ad", locals: { ad: @advertisement } %>

Это отобразит частичное представление «advertisement/_ad.html.erb», независимо от того, из какого контроллера оно вызывается.

Отображение объектов, которые отвечают на метод `to_partial_path`

Вместо явного указания расположения частичного представления, вы также можете позволить PartialRenderer выполнить эту работу и выбрать правильный путь, проверив метод `to_partial_path`.

# @account.to_partial_path returns 'accounts/account', so it can be used to replace:
# <%= render partial: "accounts/account", locals: { account: @account} %>
<%= render partial: @account %>

# @posts is an array of Post instances, so every post record returns 'posts/post' on `to_partial_path`,
# that's why we can replace:
# <%= render partial: "posts/post", collection: @posts %>
<%= render partial: @posts %>

Отображение по умолчанию

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

# Instead of <%= render partial: "account" %>
<%= render "account" %>

# Instead of <%= render partial: "account", locals: { account: @buyer } %>
<%= render "account", account: @buyer %>

# @account.to_partial_path returns 'accounts/account', so it can be used to replace:
# <%= render partial: "accounts/account", locals: { account: @account} %>
<%= render @account %>

# @posts is an array of Post instances, so every post record returns 'posts/post' on `to_partial_path`,
# that's why we can replace:
# <%= render partial: "posts/post", collection: @posts %>
<%= render @posts %>

Отображение частичных представлений с макетами

Частичные представления могут иметь свои собственные применённые макеты. Эти макеты отличаются от тех, которые заданы глобально для всего действия, но работают аналогично. Представьте список с двумя типами пользователей:

<%# app/views/users/index.html.erb &>
Here's the administrator:
<%= render partial: "user", layout: "administrator", locals: { user: administrator } %>

Here's the editor:
<%= render partial: "user", layout: "editor", locals: { user: editor } %>

<%# app/views/users/_user.html.erb &>
Name: <%= user.name %>

<%# app/views/users/_administrator.html.erb &>
<div id="administrator">
  Budget: $<%= user.budget %>
  <%= yield %>
</div>

<%# app/views/users/_editor.html.erb &>
<div id="editor">
  Deadline: <%= user.deadline %>
  <%= yield %>
</div>

…это вернёт:

Here's the administrator:
<div id="administrator">
  Budget: $<%= user.budget %>
  Name: <%= user.name %>
</div>

Here's the editor:
<div id="editor">
  Deadline: <%= user.deadline %>
  Name: <%= user.name %>
</div>

Если задана коллекция, макет будет отображён один раз для каждого элемента в коллекции. Например, эти два фрагмента имеют одинаковый вывод:

<%# app/views/users/_user.html.erb %>
Name: <%= user.name %>

<%# app/views/users/index.html.erb %>
<%# This does not use layouts %>
<ul>
  <% users.each do |user| -%>
    <li>
      <%= render partial: "user", locals: { user: user } %>
    </li>
  <% end -%>
</ul>

<%# app/views/users/_li_layout.html.erb %>
<li>
  <%= yield %>
</li>

<%# app/views/users/index.html.erb %>
<ul>
  <%= render partial: "user", layout: "li_layout", collection: users %>
</ul>

Учитывая двух пользователей, чьи имена Alice и Bob, эти фрагменты возвращают:

<ul>
  <li>
    Name: Alice
  </li>
  <li>
    Name: Bob
  </li>
</ul>

Текущий отображаемый объект, а также счётчик объектов, будут доступны в шаблоне макета в качестве локальных переменных под теми же именами, что и в частичном представлении.

Вы также можете применить макет к блоку в любом шаблоне:

<%# app/views/users/_chief.html.erb &>
<%= render(layout: "administrator", locals: { user: chief }) do %>
  Title: <%= chief.title %>
<% end %>

…это вернёт:

<div id="administrator">
  Budget: $<%= user.budget %>
  Title: <%= chief.name %>
</div>

Как видите, хэш :locals общий для частичного представления и его макета.

Если вы передаёте аргументы в «yield», то они будут переданы в блок. Один из способов использования этого — передать массив в макет и обработать его как перечислимый.

<%# app/views/users/_user.html.erb &>
<div class="user">
  Budget: $<%= user.budget %>
  <%= yield user %>
</div>

<%# app/views/users/index.html.erb &>
<%= render layout: @users do |user| %>
  Title: <%= user.title %>
<% end %>

Это отобразит макет для каждого пользователя и вызовет блок, каждый раз передавая пользователя.

Вы также можете вызывать yield несколько раз в одном макете и использовать аргументы блока, чтобы различать разделы.

<%# app/views/users/_user.html.erb &>
<div class="user">
  <%= yield user, :header %>
  Budget: $<%= user.budget %>
  <%= yield user, :footer %>
</div>

<%# app/views/users/index.html.erb &>
<%= render layout: @users do |user, section| %>
  <%- case section when :header -%>
    Title: <%= user.title %>
  <%- when :footer -%>
    Deadline: <%= user.deadline %>
  <%- end -%>
<% end %>

Константы

IDENTIFIER_ERROR_MESSAGE
OPTION_AS_ERROR_MESSAGE
PREFIXED_PARTIAL_NAMES

Публичные методы класса

new(*) Показать исходный код
# File actionview/lib/action_view/renderer/partial_renderer.rb, line 287
def initialize(*)
  super
  @context_prefix = @lookup_context.prefixes.first
end
Вызывает метод суперкласса

Публичные методы экземпляра

render(context, options, block) Показать исходный код
# File actionview/lib/action_view/renderer/partial_renderer.rb, line 292
def render(context, options, block)
  setup(context, options, block)
  identifier = (@template = find_partial) ? @template.identifier : @path

  @lookup_context.rendered_format ||= begin
    if @template && @template.formats.present?
      @template.formats.first
    else
      formats.first
    end
  end

  if @collection
    instrument(:collection, :identifier => identifier || "collection", :count => @collection.size) do
      render_collection
    end
  else
    instrument(:partial, :identifier => identifier) do
      render_partial
    end
  end
end

© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API