Rails 7.0.4中Turbo Stream无法更新yield块外的_header局部视图
解决Turbo Stream无法更新Header购物车数量的问题
核心问题
你在CartItemsController#destroy的Turbo Stream指令中,错误地将数值类型的购物车数量作为目标元素ID传入turbo_stream.update,导致Turbo无法找到对应的DOM元素进行更新。终端显示加载了局部视图,但实际没有匹配到可操作的元素,所以Header的数量指示器始终显示旧数据。
修复步骤
1. 修正Controller中的Turbo Stream目标ID
将更新目标改为Header中数量指示器的DOM元素ID(cart_quantity),直接传入最新计算的数量值:
# app/controllers/cart_items_controller.rb def destroy authorize cart_item if cart_item.destroy if cart_item.cart.cart_item_ids.any? cart_sum cart_quantity = cart_item.cart.cart_items.count respond_to do |format| format.turbo_stream do render turbo_stream: [ turbo_stream.remove(@cart_item), # 直接更新指定ID的DOM元素,传入最新数量 turbo_stream.update('cart_quantity', cart_quantity), turbo_stream.update('cart_sum', partial: 'carts/cart_sum') ] end format.html { redirect_to cart_path(current_user.cart.id) } end else redirect_to cart_path(current_user.cart.id) end end end
2. 优化购物车数量局部视图
修改_cart_quantity.html.erb,支持接收局部变量,避免依赖全局current_user的旧数据:
# app/views/carts/_cart_quantity.html.erb <%= cart_quantity || (current_user.nil? ? '' : current_user.cart.cart_items.count) %>
3. 可选:更新整个Header(如果需要)
如果需要更新整个Header而非仅数量,先给Header容器添加ID:
# app/views/shared/_header.html.erb <div class="header" id="site_header"> <!-- 原有Header内容 --> </div>
然后在Controller中更新这个容器:
turbo_stream.update('site_header', partial: 'shared/header', locals: { cart_quantity: cart_quantity })
4. 清理冗余代码
删除Controller中冗余的get_cart_quantity方法调用,直接使用已计算的cart_quantity变量即可。
验证
删除购物车商品后,终端会显示Turbo Stream正确发送了更新指令,Header中的购物车数量会实时更新,无需刷新页面。
内容的提问来源于stack exchange,提问作者Stas Fly
相关产品推荐
相关产品推荐

