Ruby on Rails: предоставление против content_for

Сегодня я наткнулся на вспомогательную функцию представления «предоставить». Изучив его руководство, я все еще не понимаю, чем он отличается от «content_for».

предоставить (имя, содержимое = ноль, & заблокировать)

То же, что и content_for, но при использовании потоковой передачи сбрасывает прямо обратно в макет. Другими словами, если вы хотите несколько раз конкатенировать один и тот же буфер при рендеринге данного шаблона, вы должны использовать content_for, если нет, используйте Provide, чтобы указать макету прекратить поиск дополнительного содержимого.

Вопрос 1: для меня это довольно абстрактно - может ли кто-нибудь конкретизировать это, приведя наглядный пример?

Вопрос 2: работа с конвейером активов, который работает лучше и почему?

Спасибо!


person Bruce    schedule 07.01.2015    source источник
comment
Знакомы ли вы с api.rubyonrails.org/classes/ActionController/Streaming.html ?   -  person Thong Kuah    schedule 07.01.2015
comment
Честно говоря, нет, пока вы не упомянули об этом. Я только что взглянул на ссылку, которой вы поделились, и она превосходна. Никогда не знал, что по умолчанию Rails загружает шаблон перед макетом! Таким образом, потоковая передача — это способ изменить этот порядок. Потом..?   -  person Bruce    schedule 07.01.2015
comment
Вот как это реализовано, основное преимущество потоковой передачи заключается в том, что части страницы (особенно заголовок JS) могут быть переданы обратно в браузер, когда он будет готов, а не ждать всей страницы.   -  person Thong Kuah    schedule 07.01.2015
comment
Звучит лучше. Но что тогда означает буфер? ... объединять несколько раз в один и тот же буфер при рендеринге данного шаблона ... Также было бы здорово, если бы вы могли написать это в ответе, чтобы я мог проголосовать за вас или принять ответ, чтобы вознаградить вас. Спасибо!   -  person Bruce    schedule 07.01.2015


Ответы (2)


Во-первых, что такое потоковая передача? Зачем вам это?

Потоковая передача — это альтернативный метод рендеринга страниц сверху вниз (снаружи внутрь). Поведение рендеринга по умолчанию — наизнанку. Потоковая передача должна быть включена в вашем контроллере:

class MyController
  def action
    render stream: true # Streaming enabled
  end
end

Согласно документации:

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

Итак, если вы не используете потоковую передачу, есть ли разница?

да.

Разница в том, что шаблон может определять несколько блоков контента, вызывая content_for несколько раз. Это объединит блоки и передаст их в макет:

# layout.html.erb
<div class="heading"><%= yield :surprise %></div>
<div class="body">
   <p><%= yield %></p>
   <p>But it's not very interesting...</p>
</div>

# template.html.erb
<%= content_for :surprise, "Hello" %>
I've got your content!
<%= content_for :surprise, ", World!" %>

# Generated HTML
<div class="heading">Hello, World!</div>
<div class="body">
   <p>I've got your content!</p>
   <p>But it's not very interesting...</p>
</div>

Поскольку provide не продолжает поиск в предоставленном шаблоне, в шаблон будет отправлен только блок, переданный первому вызову provide:

# layout.html.erb
<div class="heading"><%= yield :title %></div>

# template.html.erb
<%= provide :title, "Foo" %>
<%= provide :title, "bar" %>

# Generated HTML
<div class="heading">Foo</div>
person rodamn    schedule 24.09.2015
comment
provide также добавляет содержимое в view_flow. единственный способ перезаписать содержимое ключа — использовать content_for с опцией flush: true. - person mmtootmm; 26.05.2017

Было любопытно посмотреть, в чем разница, и поскольку Thong Kuah указал на API внутри ответа:

Это означает, что если у вас есть yield :title в макете и вы хотите использовать потоковую передачу, вам придется отображать весь шаблон (и, в конечном итоге, инициировать все запросы) перед потоковой передачей заголовка и всех ресурсов, что убивает цель потоковой передачи. По этой причине в Rails 3.1 представлен новый вспомогательный метод с именем Provide, который делает то же самое, что и content_for, но приказывает макету прекратить поиск других записей и продолжить рендеринг.

person rtfminc    schedule 05.05.2015