Вопрос по view, ruby-on-rails, render – Rails: визуализация представления (не частичного) из представления

38

У меня есть контроллер, который отвечает на обаhtml а такжеjs,html view отображает всю страницу (включая верхний и нижний колонтитулы), аjs только заменяет#main, Помимо верхнего и нижнего колонтитула оба формата отображают один и тот же контент. Я могу получить этот эффект с тремя файлами:

_show.html.erb
<div>Content!</div>

show.html.erb
<%= render "show" %>

show.js.erb
$("#main").fadeIn("<%= escape_javascript(render 'show') %>");

Это работает, но я бы предпочел, если бы мне не нужно отдельное_show частично. К сожалению, это не работает:

show.html.erb
<div>Content!</div>

show.js.erb
$("#main").fadeIn("<%= escape_javascript(render 'show') %>");

Как Rails будет искатьshow частичный, а не фактический вид.

Есть ли способ заставить Rails искать файл вида, а не частичный?

Когда-то вы могли сделать что-то подобное в контроллере, чтобы получить доступ к содержимому представления HTML-представления во время действия javascript:lookup_context.update_details(:formats => [:html]) { @content = render_to_string }, Тогда в представлении JS вы могли быrender(@content), Однако это был Rails 3.0.x, и, возможно, даже тогда он не был чистым решением. numbers1311407
К счастью, это не зацикливание. По крайней мере, пока. Сейчас я получаюmissing template ошибка. Похоже, он не может даже найти себя. nullnullnull
Спасибо за вклад. У меня было ощущение, что это может быть лучшим подходом, но я сначала хотел узнать мнение другого разработчика. В долгосрочной перспективе при таком подходе могут возникнуть некоторые проблемы с обслуживанием, особенно когда я пишу больше действий с этой функциональностью. Тем не менее, по крайней мере, в краткосрочной перспективе я могу настроить генератор для выполнения работы. nullnullnull
Визуализация не частичного представления внутри другого представления - это не совсем Rails Way ™. Ваше текущее решение, вероятно, лучше. Переименовать его_body если вы чувствуете себя странно по поводу именования. Общее, что вы увидите в этом сценарии:render(@resource)который превращается в частичный путь, напримерresources/_resource. numbers1311407
Вы могли бы использовать:file вариант, например:file => 'show', Помощник рендера неявно включит строковый аргументrender 'yourview' вrender :partial => 'yourview', Однако проблема, с которой вы столкнетесь, заключается в том, что контекст поиска в действии js будет разрешать «show» для версии js, что, вероятно, приведет к бесконечному циклу или тому подобному. numbers1311407

Ваш Ответ

4   ответа
10

как вы можете видеть по комментариям. Рельсы имеют понятияПосмотреть, частичный а такжерасположение, Тем не менее, представление является единственным, который вы должны продолжать использовать только один раз. Итак, мои предложения:

Если вы чувствуете, что в вашем текущем представлении может быть отображено более одного дополнительного вида, вы, скорее всего, ищетерасположениеЕсли вы считаете, что одно из ваших представлений должно отображаться на многих страницах, вы ищетечастичныйЕсли этот вид должен отображать только один дополнительный вид внутри него, и этот вид должен отображаться только внутри текущего вида, вы можетевыберите любой из вышеперечисленных или женичего из этого - вот и все, пойти с одним файлом
22

рендеринг другого не частичного представления в другом представлении - это «Не путь рельсов», если, тем не менее, вы все еще настаиваете на этом, один из методов:

<%= render :file => '<replace with relative/absolute path>' %>
26

- это не совсем Rails Way ™. Ваше текущее решение, вероятно, лучше, и не редкость. Переименуйте его _body или что-то еще подходящее, если вы чувствуете странность, что частичное имя совпадает с действием.

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

Этому способствует тот факт, что в некоторой степени вопреки принципу наименьшего удивления Rails создастhtml шаблон дляjs действие, если нетjs шаблон существует. Это означает, что вы можете удалить как шаблон js, так и частичный, и просто создать макет, озаглавленный, например,fadein.js.erb:

# yourviews/show.html.erb
<div>Content!</div>

# layouts/fadein.js.erb
$("#main").fadeIn("<%= escape_javascript(yield) %>");

# YourController.rb
def show
  # ...
  respond_to do |wants|
    wants.html
    wants.js { render :layout => "fadein" }
  end
end
Это сработало очень хорошо! Огромное спасибо. У меня только был вопрос, я не мог заставить это работать для сценария «создания», когда отправка формы должна перенаправить меня на запись, которую я только что создал. Я добавил remote: true в свой form_for, но он ищет шаблон создания, даже если я сделал response_to для JS, чтобы указать на файл JS макета. Какие-нибудь советы? Благодарю. Kopty
Спасибо за чаевые номера. Я попробовал это, и получаю ошибку "': show' не является ActiveModel-совместимым объектом. Он должен реализовывать: to_partial_path." Я также попытался жестко запрограммировать действие show контроллера, но это тоже не сработало. Kopty
Бесконечно благодарен. Это решение кипит три файла (show.html.erb, show.js.erb, а также_show.html.erb) в одинshow.html.erb, Я могу применить это к моделям и действиям, и все еще будет только одинlayouts/fadein.js.erb файл. Brilliant! nullnullnull
УДИВИТЕЛЬНАЯ идея, большое спасибо! Bohdan
@Kopty Он по-прежнему отображает шаблон в виде HTML внутри макета JavaScript. Так что он все равно будет искать шаблон создания как обычно, если вы не скажете, что нет. Если вы хотите визуализировать шаблон шоу, вы можете сделать что-то вродеrender :show, :layout => "fadein" numbers1311407
3

вам просто нужно передать контекст вашемуrender метод:

<%= render :template => "show" -%>

Похожие вопросы