Rails 7.0.4 Turbostream 不会刷新部分外部 yield-block

Rails 7.0.4 Turbostream does not refresh partial outside yield-block

提问人:Stas Fly 提问时间:9/26/2023 更新时间:9/26/2023 访问量:30

问:

我正在运行 rails 7.0.4。我使用 turbostream 刷新相应视图的内容,而无需重新加载所有页面。如果我刷新 <%= yield %> 块(嵌套在 application.html.erb 中)内的内容,一切都很顺利。在我的商店中,我设置了一个购物车,用于放置物品(产品)。carts/show.html.erb 反映了我放入购物车的所有商品。此外,嵌套在应用程序模板 (application.html.erb) 中的 _header.html.erb 包含指向购物车的链接和购物车中当前商品数量的指示器。我在 CartItemsController 中使用 turbostream 在相应的视图 (app/views/carts/show.html.erb) 和 app/views/shared/_header.html.erb 的 dependent 字段内进行动态内容刷新。例如,如果我删除了一个项目,那么 turbo 将正确地将记录从页面中剔除,但购物车中当前项目数量的指示器会显示旧数量,直到您刷新或重定向页面。终端显示 turbo 重新加载所有相关的部分,但实际上只有 <%= yield %> 块的内容是刷新的。

如何强制涡轮更新app/views/shared/_header.html.erb的内容?

下面是一些代码:

            # frozen_string_literal: true
    
    class CartItemsController < ApplicationController
      def create
        @cart_item = CartItem.new(cart_item_params)
        authorize cart_item
        @cart_item.save if @cart_item.valid?
        respond_to do |format|
          format.turbo_stream do
            render turbo_stream: [
              turbo_stream.update("cart_item_form_#{@cart_item.product.id}", partial: 'products/cart_item_form',
                                                                             locals: { product: @cart_item.product, products_in_cart: true })
            ]
          end
        end
      end
    
      def update
        authorize cart_item
        cart_item.update(cart_item_params)
      end
    
      def destroy
        authorize cart_item
        if cart_item.destroy
          if cart_item.cart.cart_item_ids.any?
            cart_sum
            get_cart_quantity
            cart_quantity = cart_item.cart.cart_items.count
            respond_to do |format|
              format.turbo_stream do
                render turbo_stream: [
                  turbo_stream.remove(@cart_item),
                  turbo_stream.update(@cart_quantity, partial: 'shared/header', locals: {cart_quantity: cart_quantity}),
                  # turbo_stream.replace(:cart_quantity, cart_item.cart.cart_items.count),
                  # turbo_stream.replace(cart_quantity: cart_item.cart.cart_items.count),
                  turbo_stream.update('cart_sum', partial: 'carts/cart_sum')
                ]
              format.html { render layout: 'shared/header' }
              end
            end
          else
            redirect_to cart_path(current_user.cart.id)
          end
        end
      end
    
      private
    
      def cart_item
        @cart_item ||= CartItem.find(params[:id])
      end
    
      def cart_sum
        @cart_sum = 0
        cart_item.cart.cart_items.map do |cart_item|
          @cart_sum += cart_item.quantity * cart_item.product.price
        end
      end
    
      def get_cart_quantity
        @cart_quantity = cart_item.cart.cart_items.count
      end
    
      def authorize_cart_item
        authorize cart_item
      end
    
      def cart_item_params
        params.require(:cart_item).permit(:quantity, :cart_id, :product_id)
      end
    end
    
    
    
    app/views/shared/_header.html.erb
    <div class="mobile-menu">
    </div>
    <div class="header">
      <div class="header-container">
        <div class="gap-1"></div>
        <div class="link-block">
          <div><%= link_to t('.about_us'), '#', class: 'header-link' %></div>  
          <div><%= link_to t('.payment'), '#', class: 'header-link' %></div>  
          <div><%= link_to t('.contact'), '#', class: 'header-link' %></div>  
          <div><%= link_to t('.about_project'), '#', class: 'header-link' %></div>  
        </div>
        <div class="gap-1"></div>
        <div class="menu-item"><%= link_to t('.menu', default: 'no translate'), '#', class: 'header-link' %></div>
        <div class="devise-menu">
          <% if user_signed_in? %>
            <div><%= link_to t('buttons.sign_out'), destroy_user_session_path, data: {turbo_method: :delete}, class: 'header-link' %></div>
          <% else %>
            <div><%= link_to t('buttons.sign_in'), new_user_session_path, method: :post, class: 'header-link' %></div>
            <div class="vertical-rod"><span><%= ' | ' %></span></div>
            <div><%= link_to t('buttons.sign_up'), new_user_registration_path, method: :post, class: 'header-link' %></div>
          <% end %>
        </div>
        <div class="block-cart">
          <% if user_signed_in? %>
            <div id="cart">
              <span id="cart-total">
                <%= link_to (image_tag('icon_basket.png', alt: t('.cart'), class: 'header-link' )), cart_path(current_user.cart.id)%>
                <span class="cart-quantity" id="cart_quantity"><%= render partial: 'carts/cart_quantity' %></span>
              </span>
            </div>
          <% end %>
          
        </div>
        <div class="languages">
          <div><%= link_to_unless_current 'UK', url_for(locale: :uk), class: 'header-link' %></div>
          <div class="vertical-rod"><span> | </span></div>
          <div><%= link_to_unless_current 'EN', url_for(locale: :en), class: 'header-link' %></div>
        </div>
      </div>
      
    </div>
    
    
    
    app/views/carts/_cart_quantity.html.erb
    <% @cart_quantity = current_user.nil? ? '' : current_user.cart.cart_items.count %>
    <%= @cart_quantity %>
    
    
    
    app/views/layouts/application.html.erb
    <!DOCTYPE html>
    <html>
      <head>
        <title>Veselka</title>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <%= csrf_meta_tags %>
        <%= csp_meta_tag %>
    
        <%= stylesheet_link_tag "application", media: "all", "data-turbo-track": "reload" %>
        <%= javascript_importmap_tags %>
        <%= javascript_include_tag 'turbo', defer: true, "data-turbo-track": "reload" %>
        <%= javascript_include_tag 'products' %>
      </head>
    
      <body>
        <%= render 'shared/header' %>
        <div class="start-block container">
          <div class="header-msg-container">
            <% if flash.any? %>
              <%= render 'shared/messages' %>
            <% else %>
             <div class="breadcrumbs"><%= render_breadcrumbs :separator => ' / ' %></div>
            <% end %>
            <% render 'shared/messages' %>
          </div>
          <div class="content-container">
            <div class="gap-3"></div>
            <div class="sidebar-container">
              <div class="logo">
                <%= link_to root_path do %>
                  <%= image_tag('veselka_logo.jpg', class: 'logo-main') %>
                <% end %>
              </div>
              <div class="category" id="categories"><%= link_to t('.categories'), product_categories_path %></div>
              <% ProductCategory.all.order(name: :asc).map do |product_category| %>
                <div class="category"><%= link_to "#{product_category.name}", product_category_path(product_category, product_category_id: product_category.id) %></div>
              <% end %>
            </div>
            <div class="yield-container">
              <%= yield %>
            </div>
            <div class="gap-3"></div>
          </div>
        </div>
    
        <%= render 'shared/footer' %>
      </body>
    </html>
    
Ruby-on-Rails 部分 涡轮增压

评论


答:

1赞 Stas Fly 9/26/2023 #1

我发现了错误。我尝试在控制器()中更新实例变量@cart_quantity,但必须更新ID。因此,生成的代码行必须如下所示: .应更新 ID“cart”。我的犯规。turbo_stream.update(@cart_quantity, partial: 'shared/header', locals: {cart_quantity: cart_quantity}),turbo_stream.replace('cart', partial: 'shared/header', locals: {cart_quantity: cart_quantity}),