Разница между рендерингом и рендерингом частичной и доходности
Я прочитал его из руководств Rails, посмотрел книгу Micheal Hartel и теперь читаю ее из книги Rails View, но все же я запутался: (
Существует файл _footer.html.erb
, поэтому он является "частичным" и в коде, который он написал:
<%=render 'layouts/footer' %>
поэтому я понимаю, что, когда он видит это, идет и вставляет HTML-код для нижнего колонтитула здесь. ОК...
Теперь несколько страниц позже говорят:
<%= render partial: 'activitiy_items/recent' %>
поэтому ПОЧЕМУ на этот раз у нас есть слово "частичное" здесь, но у нас его не было в предыдущем?
И где-то еще я вижу <%= yield :sidebar %>
Итак, этот yield
также вставляет HTML на свое место? Ну, разве это не то, что делал render
?
Я надеялся, что другой программист вместо книг объяснит это мне, может быть, я получу его на этот раз:)
Ответы
Ответ 1
render
и render partial:
-
render 'some_view'
- сокращение для render partial: 'some_view'
. -
render file: 'view'
будет искать файл view.html.erb
и NOT _view.html.erb
(.erb
или любой другой визуализатор вы используете) -
render
не будет принимать дополнительные локальные переменные для партиала, вам нужно использовать render partial:
как показано ниже:
render partial: 'some/path/to/my/partial', locals: { custom_var: 'Hello' }
(http://guides.rubyonrails.org/layouts_and_rendering.html#passing-local-variables)
yield
& content_for
-
yield
обычно используется в макетах. Он говорит Rails поместить содержимое этого блока в это место в макете. - Когда вы делаете
yield :something
связанное с content_for :something
, вы можете передать блок кода (представление), чтобы отобразить место yield :something
(см. Пример ниже).
Небольшой пример о доходности:
В вашем макете:
<html>
<head>
<%= yield :html_head %>
</head>
<body>
<div id="sidebar">
<%= yield :sidebar %>
</div>
</body>
В одном из ваших представлений:
<% content_for :sidebar do %>
This content will show up in the sidebar section
<% end %>
<% content_for :html_head do %>
<script type="text/javascript">
console.log("Hello World!");
</script>
<% end %>
Это создаст следующий HTML:
<html>
<head>
<script type="text/javascript">
console.log("Hello World!");
</script>
</head>
<body>
<div id="sidebar">
This content will show up in the sidebar section
</div>
</body>
Сообщения, которые могут помочь:
Ссылки на документацию и руководства:
Ответ 2
О render, render: partial и yield
-
render: template and render: partial - это два файла в рельсах..
render: шаблон в основном создается в соответствии с действием с синтаксисом demo.html.erb
render: partial повторно используются и вызывается из разных представлений, разделяются между многими страницами в приложении, а синтаксис - _demo.html.erb
-
доходность и рендеринг.
Выход - это способ вызова блока кода с его выходом, но рендеринг будет включать в себя шаблон частичной страницы, где он вызывается. В rails выход в основном используется в макете, тогда как рендер используется в действиях или их шаблонах
Ответ 3
Некоторые разработчики думают о redirect_to как о какой-то команде goto, перемещая исполнение из одного места в другое в вашем Rails-коде. Это неверно. Ваш код перестает работать и ждет нового запроса для браузера. Просто случается, что вы сказали браузеру, какой запрос он должен сделать дальше, отправив код статуса HTTP 302.
Рассмотрим эти действия, чтобы увидеть разницу:
def index
@books = Book.all
end
def show
@book = Book.find_by(id: params[:id])
if @book.nil?
render action: "index"
end
end
С кодом в этой форме, вероятно, будет проблема, если переменная @book
равна nil. Помните, что render :action
не запускает какой-либо код в целевом действии, поэтому ничто не будет настраивать переменную @books, которая, вероятно, потребует индекс. Один из способов исправить это - перенаправить вместо рендеринга:
def index
@books = Book.all
end
def show
@book = Book.find_by(id: params[:id])
if @book.nil?
redirect_to action: :index
end
end
С помощью этого кода браузер сделает новый запрос для индексной страницы, код в методе индекса будет запущен, и все будет хорошо.
Единственный недостаток этого кода заключается в том, что для обозревателя требуется двусторонняя поездка: браузер запрашивал действие show с /books/ 1, и контроллер обнаружил, что книг нет, поэтому контроллер отправляет ответ перенаправления 302 браузер, говорящий ему перейти в /books/, браузер соглашается и отправляет новый запрос обратно на контроллер, запрашивая теперь действие индекса, контроллер затем получает все книги в базе данных и отображает шаблон индекса, отправляет его обратно до браузера, который затем показывает его на экране.
Хотя в небольшом приложении эта добавленная задержка может не быть проблемой, нужно подумать о том, является ли время отклика проблемой. Мы можем продемонстрировать один из способов справиться с этим надуманным примером:
def index
@books = Book.all
end
def show
@book = Book.find_by(id: params[:id])
if @book.nil?
@books = Book.all
flash.now[:alert] = "Your book was not found"
render "index"
end
end
Это позволит обнаружить, что нет книг с указанным ID, заполняет переменную экземпляра @books всеми книгами в модели, а затем непосредственно визуализирует шаблон index.html.erb, возвращая его в браузер со вспышкой чтобы сообщить пользователю, что произошло.