求助:使用Turbo Frames和Streams递归渲染评论回复的实时显示问题
问题解决:Turbo Streams/Frames 实时渲染评论回复
核心问题分析
你的代码存在两个关键错误:
- 父评论的回复容器仅在已有回复时才渲染,导致新回复创建时Turbo找不到目标DOM元素
- Turbo流模板错误地遍历新回复的
replies(空集合),而非直接将新回复插入父评论的容器
步骤1:修正评论Partial模板
给每个评论添加固定存在的回复容器,无论当前是否有回复,确保Turbo能定位到目标元素:
<%= turbo_frame_tag comment do %> <div> <p class="mt-4 text-gray-500 dark:text-gray-400"><%= comment.body %></p> </div> <%= turbo_frame_tag dom_id(Comment.new) do %> <%= render "comments/like_button", comment: comment %> <% end %> <!-- 固定的回复容器:无论有没有回复都保留 --> <div class="ml-4"> <%= turbo_frame_tag nested_dom_id(comment, "replies") do %> <% comment.replies.each do |reply| %> <%= render 'comments/comment', comment: reply %> <% end %> <% end %> </div> <% end %>
步骤2:修正Turbo流模板
直接将新创建的回复插入父评论的回复容器,而非遍历空集合:
<%= turbo_stream.update dom_id(Comment.new), "" %> <% if @comment.parent_id.nil? %> <%= turbo_stream.prepend "comments", @comment %> <% else %> <!-- 定位到父评论的回复容器,插入新回复 --> <%= turbo_stream.prepend nested_dom_id(@comment.parent, "replies") do %> <%= render 'comments/comment', comment: @comment %> <% end %> <% end %>
步骤3:确保控制器与表单正确关联
- 控制器
create动作需正确设置父评论关联:
def create @post = Post.find(params[:post_id]) @comment = @post.comments.build(comment_params) @comment.user = current_user # 接收表单传递的parent_id @comment.parent_id = params[:comment][:parent_id] if @comment.save # Turbo自动渲染对应turbo流模板 else # 处理错误逻辑 end end
- 回复表单需正确传递
parent_id:
<%= form_with model: [@post, Comment.new], locals: { parent_comment: comment } do |f| %> <%= f.hidden_field :parent_id, value: parent_comment.id %> <%= f.text_area :body, placeholder: "写下你的回复..." %> <%= f.submit "回复", class: "mt-2 btn" %> <% end %>
内容的提问来源于stack exchange,提问作者mutebi godfrey
相关产品推荐
相关产品推荐

