简体   繁体   中英

Rails: Render a View (not a partial) From Within a View

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?

Rendering a non-partial view inside another view isn't exactly the Rails Way™. Your current solution is probably better, and not an uncommon approach. Rename it _body, or something else appropriate, if you feel weird about the the partial name being the same as the action.

However if your view can be shared, as it seems like it could in this case, you could just make it a layout.

This is facilitated by the fact that, somewhat against the principle of least surprise, Rails will render an html template for a js action if no js template exists. This means that you could remove both the js template, and the partial, and just create a layout entitled, for example, 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

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

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

This is not a good practice as you can see by the comments. Rails have the concepts of view , partial and layout . That said, the view is the only one you should keep using only once. So my suggestions are:

  1. If you feel that more than one extra view could be rendered inside your current view, you are most likely looking for a layout
  2. If you feel that one of your views should be rendered in many pages, you are looking for a partial
  3. If this view should render only one extra view inside it, and that view should only be rendered inside the current view, you can pick any of the above or none of it - that's it, go with a single file

你只需要将一个上下文传递给你的render方法:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM