你能从一个控制器动作渲染多个视图/相同的布局吗?

时间:2018-03-11 03:23:07

标签: javascript ruby-on-rails layout view render

重要背景:

我正在构建一个渐进的网络应用程序。例如,new操作可能有一系列步骤,其中每个步骤都有一个明确的,离散的页面专用于JUST该步骤:

  1. 找到您要订购的商品(一些有用的指南)
  2. 将其带到退房点(一些有用的指导方针)
  3. 退房(一些有用的指导方针)
  4. 在出门的路上锁上门
  5. 所有页面共享具有一些通用功能的单个布局(例如,每个步骤上的下一个/后退按钮)。这个想法是页面视图看起来像这样:

    <div id="step-1">
    <div id="step-2" class="hidden">
    <div id="step-3" class="hidden">
    <div id="step-4" class="hidden">
    

    每个步骤中都有下一个/后退按钮,其中javascript隐藏/取消隐藏其他页面。用户从不真正提交任何内容,它实际上只是指导用户完成一系列步骤,而无需将其重定向到多个控制器操作(以及单独的视图文件),这会增加加载时间。

    我正在试图找出组织我的视图代码的策略。对我来说最有意义的是这样的事情

    views
      layouts
        progressive_layout.html.erb
      orders
        new
          step_1.html.erb
          step_2.html.erb
          step_3.html.erb
          step_4.html.erb       
    

    以上内容对我来说非常干净,我觉得最容易管理,知道在哪里编辑。对于其他上下文,之前,我有一个文件,在控制器中,我基本上有一些荒谬的实例变量来定义视图文件中的各种内容。这不起作用。

    问题在于,只需一个动作,我该如何实现渲染?显然我不能做下面的事情(因为render每个动作只能调用一次):

    def new
      4.times do |i|
        render "orders/new/step_#{i}", layout: "progressive_layout"
      end
    end
    

    唯一真正的方法是多次进入progressive_layout

    <% 4.times do |i| %>
       <!-- generic content -->
       <%= render "orders/new/step_#{i}" %> <!-- partialize the unique content -->
       <!-- generic content -->
    <% end %>
    

    但这仍然非常笨重,因为progressive_layout再次用于可能有多于/少于4步的其他行动。基本上我想找到一种非常简洁的方法,允许单个动作构建X个“布局独特内容”对。

    这可能吗?

    如果没有,我在想我可能要做的就是让控制器只渲染第一步,然后下一个按钮将AJAX提交给另一个控制器动作,该动作将拉下正确的下一步渲染。

1 个答案:

答案 0 :(得分:0)

Rails不允许多次渲染。

views
  layouts
    progressive_layout.html.erb
  orders
    new
      step.html.erb
      _step_1.html.erb
      _step_2.html.erb
      _step_3.html.erb
      _step_4.html.erb


#controller
render "orders/new/step", layout: "progressive_layout"


# In step.html.erb
<% 4.times do |i| %>
   <!-- generic content -->
   <%= render "step_#{i}" %> <!-- partialize the unique content -->
   <!-- generic content -->
<% end %>

更新

您可以从外面传递参数并检查部分内容。 Doc local variables

# In step.html.erb
<%= render partial: "step_#{i}", locals: {hidden: true} %>

# In _step_1.html.erb
 <div class="<%= hidden ? 'hidden': '' %>">