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

在Rails中结合Hotwire与Stimulus使用turbo:frame-load事件时触发失败

问题原因

turbo:frame-load、turbo:before-frame-render、turbo:frame-render 这类事件仅在Turbo Frame通过导航行为加载内容时触发(比如点击Frame内的链接、通过Frame的src属性加载远程内容)。而你使用的turbo_stream.update是直接替换Frame内部的DOM内容,属于静态DOM更新,不会触发这类Frame专属的加载/渲染事件。

解决方案

提供两种可行的处理方式:

方式一:监听全局turbo:render事件

Turbo会在所有内容渲染完成(包括Turbo Stream更新)后触发全局的turbo:render事件,你可以在Stimulus控制器中监听这个事件,然后判断目标Frame是否被更新:

修改logger_controller.js:

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  connect() {
    document.addEventListener("turbo:render", this.handleFrameUpdate.bind(this))
  }

  disconnect() {
    // 控制器销毁时移除监听,避免内存泄漏
    document.removeEventListener("turbo:render", this.handleFrameUpdate.bind(this))
  }

  handleFrameUpdate(event) {
    const targetFrame = document.getElementById("europe-calculation-fields")
    // 检查当前渲染内容是否包含目标Frame
    if (event.target.contains(targetFrame)) {
      console.log("欧洲计算字段Frame已更新")
      // 执行你的业务逻辑
    }
  }
}

方式二:手动触发自定义事件

在Turbo Stream更新时,额外添加脚本手动触发自定义事件,再在Frame上监听这个事件:

1. 修改Turbo Stream模板

= turbo_stream.update "europe-calculation-fields", render("finalize_screens/europe_calculation_fields")
# 添加自定义事件触发脚本
= turbo_stream.append "europe-calculation-fields", "<script>document.getElementById('europe-calculation-fields').dispatchEvent(new CustomEvent('europe-frame-updated'))</script>"

2. 修改视图中的Frame绑定

div data-controller="logger"
  = turbo_frame_tag "europe-calculation-fields",
    data: { action: "europe-frame-updated->logger#log" } do
    = render "europe_calculation_fields"

这样每次Turbo Stream更新Frame后,都会触发自定义的europe-frame-updated事件,进而调用logger#log方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 19:46:13