You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails Hotwire嵌套Turbo Frame用src懒加载时找不到框架的问题

Rails 8/Hotwire Turbo Frame 懒加载评论编辑功能异常问题解决

问题现象

使用Turbo Frame的src属性懒加载评论列表时,点击评论的编辑链接会触发Turbo错误:

Uncaught (in promise) Error: The response (200) did not contain the expected <turbo-frame id="comment_155e1b8a-7476-41fb-bbc1-812899c438d6">

但内联渲染评论列表时,编辑功能完全正常。

核心原因分析

  1. ID匹配错误:Turbo请求编辑页面后,会在响应中查找链接指定的data-turbo-frame对应的ID,如果两者不匹配就会报错。懒加载场景下,可能存在评论partial中dom_id(comment, :edit)生成的ID与编辑页面Frame ID不一致的情况。
  2. 代码笔误:你的代码中存在明显的拼写错误(比如评论partial文件名commmets/_comments.html.erb、用户详情页中错误的dom_id(skill, :edit)),这些笔误在懒加载场景下会被放大,导致Turbo无法正确识别目标Frame。
  3. 嵌套Frame上下文问题:懒加载的评论列表会被替换到父Frame内部,Turbo在处理嵌套Frame内的链接时,可能会错误解析目标Frame的上下文。

解决方案

1. 修正所有代码笔误

  • 将评论partial文件名改为comments/_comment.html.erb(单数,对应单个评论渲染,render @user.comments会自动遍历每个评论调用该partial)。
  • 删除用户详情页中错误的<%= turbo_frame_tag dom_id(skill, :edit) %>,Turbo会自动创建不存在的目标Frame,无需提前声明。

2. 确保ID完全匹配

评论partial(comments/_comment.html.erb)

确认编辑链接的data-turbo-frame生成的ID与编辑页面的Frame ID完全一致:

<%= turbo_frame_tag comment do %>
  <%= link_to edit_user_comment_path(comment.user, comment), 
      data: { turbo_frame: dom_id(comment, :edit) } do %>
    edit comment
  <% end %>
  <%= comment.body %>
<% end %>

编辑页面(comments/edit.html.erb)

确保Frame ID与链接指定的ID完全匹配:

<%= turbo_frame_tag dom_id(@comment, :edit) do %>
  <%= form_with(model: [@comment.user, @comment]) do |f| %>
    <%= f.text_area :body, value: @comment.body %>
    <%= f.submit "Update Comment" %>
  <% end %>
<% end %>

3. 检查懒加载控制器逻辑

确保comments#index控制器正确传递变量,保证评论对象的完整性:

# app/controllers/comments_controller.rb
def index
  @user = User.find(params[:user_id])
  @comments = @user.comments.ordered
end

4. 验证渲染后的HTML

在浏览器开发者工具中检查:

  • 编辑链接的data-turbo-frame属性值是否为comment_xxx_edit格式。
  • 懒加载后的评论Frame是否正确嵌套在父Frame内,且每个评论的ID正确。

额外优化建议

如果需要在固定位置展示编辑表单,可以在用户详情页添加一个容器,让Turbo将编辑Frame插入到该容器中:

<%# users/show.html.erb %>
<%= turbo_frame_tag dom_id(@user, "comments"), src: polymorphic_url([@user, :comments]) %>

<!-- 编辑表单容器 -->
<div id="comment_edit_container"></div>

然后修改编辑链接,指定插入目标:

<%= link_to edit_user_comment_path(comment.user, comment), 
    data: { 
      turbo_frame: dom_id(comment, :edit),
      turbo_target: "comment_edit_container" 
    } do %>
  edit comment
<% end %>

内容的提问来源于stack exchange,提问作者fluxsaas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 23:44:58