42

I have a controller that responds to both html and js. The html view renders the whole page (including the header and footer), while the js only replaces #main. Aside from the header and footer, both formats render the same content. I can get this effect with three files:

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

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

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

This works, but I'd prefer if I didn't need a separate _show partial. Unfortunately, this doesn't work:

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

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

As Rails will look for the show partial, not the actual view.

Is there a way to get Rails to look for the view file, rather than a partial?

4

4 回答 4

26

在另一个视图中渲染一个非局部视图并不完全是 Rails Way™。您当前的解决方案可能更好,而不是一种不常见的方法。如果您对部分名称与动作相同感到奇怪,请将其重命名为 _body 或其他适当的名称。

但是,如果您的视图可以共享,就像在这种情况下可以共享的那样,您可以将其设置为布局。

这是因为有点违背最小意外原则,如果不存在模板,Rails 将为动作呈现html模板。这意味着您可以删除 js 模板和部分模板,只需创建一个名为的布局,例如:jsjsfadein.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
于 2013-05-02T14:21:07.053 回答
25

就像其他人提到的那样,在另一个视图中呈现另一个非部分视图是“不是轨道方式”,但是如果你仍然坚持这样做,一种方法是:

<%= render :file => '<replace with relative/absolute path>' %>
于 2015-02-02T07:31:25.643 回答
10

正如您从评论中看到的那样,这不是一个好的做法。Rails 有视图部分布局的概念。也就是说,该视图是您应该只使用一次的唯一视图。所以我的建议是:

  1. 如果您觉得在当前视图中可以渲染多个额外的视图,那么您很可能正在寻找一种布局
  2. 如果您觉得您的某个视图应该在许多页面中呈现,那么您正在寻找部分视图
  3. 如果此视图应仅在其中呈现一个额外的视图,并且该视图应仅在当前视图中呈现,则您可以选择上述任何一种选择任何一种-仅此而已,使用单个文件
于 2013-05-02T01:32:45.987 回答
7

您只需要将上下文传递给您的render方法:

<%= render :template => "show" -%>
于 2016-11-19T12:42:42.237 回答