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

如何在Rails 7的create.turbo_stream.erb文件中执行JavaScript代码?

Rails 7 Turbo Stream中执行JavaScript隐藏弹窗的解决方案

问题背景

在Rails 7项目开发评论功能时,Comment控制器的create动作在评论保存成功后返回turbo_stream格式响应。但在create.turbo_stream.erb中直接编写console.log语句或<script>标签无法执行JavaScript代码,需要实现评论创建成功后隐藏弹窗div的需求。

原相关代码

Comment控制器代码:

def create
  @comment = current_user.comments.new(comment_params)
  @feed = Feed.find(params[:comment][:feed_id])
  @comment.commentable = @feed
  @parent = params[:comment][:parent] if params[:comment][:parent].present?
  respond_to do |format|
    if @comment.save
      format.turbo_stream
      format.html { redirect_to feeds_path, notice: "Comment was successfully created." }
      format.json { render :show, status: :created, location: @comment }
    else
      format.html { render :new, status: :unprocessable_entity }
      format.json { render json: @comment.errors, status: :unprocessable_entity }
    end
  end
end

原create.turbo_stream.erb代码:

<%if @parent.present?%>
   <%= turbo_stream.update("feeds-list-parent-#{@parent}",
        partial: "feeds/feed",
        locals: { feed: @feed }) %>
<%else%>
    <%= turbo_stream.update("feeds-list-#{@feed.id}",
        partial: "feeds/feed",
        locals: { feed: @feed }) %>
<%end%>
console.log('hi') # 此处无输出,<script>标签也无法生效

解决方案

Turbo Stream不允许在模板中直接写入裸的JavaScript代码或未通过Turbo动作包裹的<script>标签。要执行JS逻辑,需通过turbo_stream.append(或其他Turbo动作)将<script>标签插入到页面的某个元素中,Turbo会自动执行该脚本。

步骤1:在页面中添加脚本承载元素

在application.html.erb的<body>内添加一个隐藏的div,用于承载Turbo插入的脚本:

<div id="turbo-scripts" style="display: none;"></div>

步骤2:修改create.turbo_stream.erb实现弹窗隐藏

在现有Turbo Stream代码后追加脚本逻辑,替换为你的弹窗ID即可实现隐藏:

<%if @parent.present?%>
   <%= turbo_stream.update("feeds-list-parent-#{@parent}",
        partial: "feeds/feed",
        locals: { feed: @feed }) %>
<%else%>
    <%= turbo_stream.update("feeds-list-#{@feed.id}",
        partial: "feeds/feed",
        locals: { feed: @feed }) %>
<%end%>

<%= turbo_stream.append "turbo-scripts" do %>
  <script>
    console.log('评论创建成功');
    // 替换为你的弹窗实际ID
    const commentModal = document.getElementById('your-comment-modal-id');
    if (commentModal) {
      commentModal.style.display = 'none';
      // 若使用Bootstrap模态框,可改用以下代码:
      // const modal = bootstrap.Modal.getOrCreateInstance(commentModal);
      // modal.hide();
    }
  </script>
<% end %>

补充方案(Rails 7.1+适用)

若项目使用Rails 7.1及以上版本,可直接使用turbo_stream.invoke调用前端预定义函数,无需插入script标签:

  1. 在create.turbo_stream.erb中添加:
<%= turbo_stream.invoke :hide_comment_modal %>
  1. 在前端JS文件中定义对应函数:
function hideCommentModal() {
  const commentModal = document.getElementById('your-comment-modal-id');
  if (commentModal) commentModal.style.display = 'none';
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 20:11:21