【问题标题】:How to properly render collection in a partial layout from inside another partial layout?如何从另一个部分布局内部正确呈现部分布局中的集合?
【发布时间】:2012-05-29 21:45:42
【问题描述】:

我有一个购物车,我想在我的应用中以 3 种不同的方式呈现。

  1. 在边栏中。仅显示购物车中的商品数量及其总价。
  2. 在购物车主视图中。显示带有每个项目的产品、数量和总价链接的行项目。还显示增加/减少商品数量的按钮和从购物车中删除商品的按钮。
  3. 在订单视图中,显示购物车内容的方式与主购物车视图相同,但产品链接、更改数量的按钮和“删除”按钮除外。

到目前为止,我这样渲染购物车:

carts/_cart.html.erb

<%= yield %>

购物车侧边栏布局carts/_sidebar.html.erb

<ul>
  <li class="nav-header">Your Cart (<%= pluralize(@cart.total_items, "Item") %>)</li>
  <li>Total Due: <%= number_to_euro(@cart.total_price) %></li>
  <% unless @cart.line_items.empty? %>
  <li><%= link_to "View Cart & Checkout", cart_path(@cart) %></li>
  <li><%= link_to "Empty Cart", @cart, :method => :delete %></li>
  <% end %>
</ul>

&lt;%= render :partial =&gt; 'carts/cart', :layout =&gt; 'carts/sidebar' %&gt;layouts/_sidebar.html.erb渲染

购物车主布局carts/_main.html.erb

<table>
  <tr>
    <th>Product</th>
    <th>Quantity</th>
    <th>Price</th>
    <th>Subtotal</th>
    <th></th>
  </tr>
  <%= render @line_items %>
  <tr id="total_line">
    <td colspan="3">Total:</td>
    <td><%= number_to_euro(@cart.total_price) %></td>
    <td></td>
  </tr>
</table>

carts/show.html.erb渲染

<h1><%= pluralize(@cart.total_items, "Item") %> in Your Cart</h1>
<%= render :partial => 'cart/cart', :layout => 'carts/main' %>
<%= link_to "Empty Cart", @cart, :method => :delete %>
<%= link_to "Checkout", new_order_path %>

还有carts/_order.html.erb,目前从orders/new.html.erb 渲染,与购物车主视图中的方式相同。

我想做的是创建 2 个不同的布局来呈现来自 carts/show.html.erborders/new.html.erb 的订单项。为此,我在line_items/_line_item.html.erb 中有&lt;%= yield %&gt;

购物车主布局的订单项布局line_items/_main.html.erb

<tr>
  <td><%= link_to "#{line_item.product.brand.name} #{line_item.product.title}", product_path(line_item.product) %></td>
  <td>
    <%= link_to "-", decrement_line_item_path(line_item), :method => :post %>
    <%= line_item.quantity %>
    <%= link_to "+", increment_line_item_path(line_item), :method => :post %>
  </td>
  <td><%= number_to_euro(line_item.product.price) %></td>
  <td><%= number_to_euro(line_item.total_price) %></td>
  <td><%= link_to "Remove"), line_item, :method => :delete %></td>
</tr>

新订单视图的类似订单项布局line_items/_order.html.erb

<tr>
  <td><%= "#{line_item.product.brand.name} #{line_item.product.title}" %></td>
  <td><%= line_item.quantity %></td>
  <td><%= number_to_euro(line_item.product.price) %></td>
  <td><%= number_to_euro(line_item.total_price) %></td>
</tr>

这就是问题的开始。我不明白如何呈现集合。我尝试像这样渲染来自carts/_main.html.erb 的订单项

<%= render :partial => 'line_items/line_item', :layout => 'line_items/main', :collection => @line_items %>

像这样来自carts/_order.html.erb

<%= render :partial => 'line_items/line_item', :layout => 'line_items/order', :collection => @line_items %>

但我在 Carts#show 中遇到 LocalJumpError

Showing app/views/line_items/_line_item.html.erb where line #1 raised:

no block given (yield)

任何其他 :collection 名称都不会呈现任何内容。我做错了什么?

【问题讨论】:

    标签: ruby-on-rails partial yield


    【解决方案1】:

    好的,我明白我做错了什么。首先,错误消息no block given (yield) 表示没有什么可以让步。其次,在这种情况下,在渲染局部时不需要使用 :layout 。

    要从layouts/_sidebar.html.erb 渲染购物车,只需调用&lt;%= render :partial =&gt; 'carts/sidebar' %&gt;

    有一件事我不知道。当使用集合渲染部分时,:partial name 的第二部分成为该集合内的局部变量名。

    这是主购物车视图的部分视图 (carts/_cart.html.erb):

    <table>
      <tr>
        <td>Product</th>
        <td>Price</th>
        <td>Quantity</th>
        <td>Subtotal</th>
        <td></th>
      </tr>
      <%= render :partial => 'line_items/cart_item', :collection => @line_items %>
      <tr>
        <td colspan="3">Total:</td>
        <td><%= number_to_euro(@cart.total_price) %></td>
        <td></td>
      </tr>
    </table>
    

    可以由&lt;%= render @cart %&gt; 渲染。注意:partial 名称中的/cart_item 部分。这就是我们在line_items/_cart_item.html.erb 中引用收藏项的方式:

    <tr>
      <td><%= link_to "#{cart_item.product.brand.name} #{cart_item.product.title}", product_path(cart_item.product) %></td>
      <td><%= number_to_euro(cart_item.product.price) %></td>
      <td>
        <%= link_to "-"), decrement_line_item_path(cart_item), :method => :post %>
        <%= cart_item.quantity %>
        <%= link_to "+"), increment_line_item_path(cart_item), :method => :post %>
      </td>
      <td><%= number_to_euro(cart_item.total_price) %></td>
      <td><%= link_to "Remove"), cart_item, :method => :delete %></td>
    </tr>
    

    与订单控制器中显示的购物车相同。 carts/_order.html.erb:

    ...
    <%= render :partial => 'line_items/order_item', :collection => @line_items %>
    ...
    

    line_items/_order_item.html.erb:

    <tr>
      <td><%= "#{order_item.product.brand.name} #{order_item.product.title}"%></td>
      <td><%= number_to_euro(order_item.product.price) %></td>
      <td>&times; <%= order_item.quantity %></td>
      <td><%= number_to_euro(order_item.total_price) %></td>
      <td></td>
    </tr>
    

    希望这一切都有意义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多