Rails:从视图中渲染视图(不是部分视图)

nul*_*ull 38 ruby-on-rails render view

我有一个控制器,既响应htmljs.该html视图使得整个页面(包括页眉和页脚),而js只替换#main.除了页眉和页脚之外,两种格式都呈现相同的内容.我可以通过三个文件获得此效果:

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

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

show.js.erb
$("#main").fadeIn("<%= escape_javascript(render 'show') %>");
Run Code Online (Sandbox Code Playgroud)

这有效,但我更喜欢如果我不需要单独的_show部分.不幸的是,这不起作用:

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

show.js.erb
$("#main").fadeIn("<%= escape_javascript(render 'show') %>");
Run Code Online (Sandbox Code Playgroud)

由于Rails会查找show部分视图,而不是实际视图.

有没有办法让Rails查找视图文件,而不是部分?

num*_*407 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
Run Code Online (Sandbox Code Playgroud)

  • 太感谢了.这个解决方案将三个文件(`show.html.erb`,`show.js.erb`和`_show.html.erb`)放到一个`show.html.erb`中.我可以跨模型和动作应用它,并且仍然只需要一个`layouts/fadein.js.erb`文件.辉煌! (4认同)

Tik*_*boy 22

像其他人提到的那样,在另一个视图中渲染另一个非局部视图是"不是轨道方式",如果你仍然坚持这样做,一种方法是:

<%= render :file => '<replace with relative/absolute path>' %>
Run Code Online (Sandbox Code Playgroud)


fot*_*nus 10

您可以通过评论看到这不是一个好习惯.Rails具有视图,部分布局的概念.也就是说,视图是您应该只使用一次的视图.所以我的建议是:

  1. 如果您觉得可以在当前视图中呈现多个额外视图,那么您很可能正在寻找布局
  2. 如果您认为您的某个视图应该在许多页面中呈现,那么您正在寻找一个部分视图
  3. 如果此视图应该只在其中呈现一个额外的视图,并且该视图应仅在当前视图中呈现,则可以选择上述任何一个选择任何一个 - 就是这样,使用单个文件


GMs*_*soF 6

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

<%= render :template => "show" -%>
Run Code Online (Sandbox Code Playgroud)