新手问题 无法监听到 turbo:render 事件

qinsicheng · 2023年09月24日 · 最后由 qinsicheng 回复于 2023年09月25日 · 652 次阅读

这是我的 Turbo Stream 操作:

<%= turbo_stream.prepend "words", @word %>

我希望通过监听turbo:render事件,在此从 DOM 来获取新加入的 @word 渲染的节点,并对其样式进行修改。但是发现监听不到该事件,但是页面上已经成功显示了新加的数据

我目前可以监听到的事件有:

  1. turbo:load
  2. turbo:before-cache
  3. before-stream-render

有什么办法能在 Turbo Stream 返回数据并修改 dom 后,进行某些操作?

我在 app/javascript/application.js 中写的:

document.addEventListener("turbo:render", function (event) {
    console.log("turbo:render")
});

当一个元素出现在页面时执行某操作,更适合用 sitmulus。

https://turbo.hotwired.dev/reference/events 根据提示来看 应该就是监听 turbo:render.

turbo:render fires after Turbo renders the page. This event fires twice during an application visit to a cached location: once after rendering the cached version, and again after rendering the fresh version.

另外 是不是应该在 html 上加?

Turbo fires events on the document.documentElement object (i.e., the element).

turbo:render 也许对应 turbo visit 和 cache render,不包括 stream render。

4 楼 已删除
5 楼 已删除
jicheng1014 回复

我目前找到两个有效的解决办法(但实际只是换了种方式执行,并没有解决我提到的根本问题):

1 . Hotwire Discussion 中提到的:

add a Stimulus data-controller attribute to the element you render inside the element. Then implement the connect() method on that controller to know when the element has been loaded into the document.

通过在被渲染的 frame 上加入 Stimulus,通过 connect() 触发函数,执行想要的操作

2 . Github Issue

document.addEventListener("turbo:before-stream-render", function (event) {
  event.preventDefault();
  event.detail.newStream.performAction();
  console.log("执行你想要的操作")   这个解决方式稍微能好点儿
});
jicheng1014 回复

我把文档所有的事件都试了一遍😅 ,还是得去 issues 里面找答案😭

8 楼 已删除

其实就像 Rei 说的,应该用 Stimulus。Stimulus 的 target 也有 connected 钩子

我补充一点为什么应该用 stimulus。

Turob 环境下 document.addEventListener 是全局的,去到别的页面这个监听器依然存在(除非再实现解绑逻辑),然后每次 stream render 都要判断有没有需要处理的内容存在。

而 stimulus 是让元素成为自行管理的组件,要优于事件绑定。

Rei 回复

受教了😃

需要 登录 后方可回复, 如果你还没有账号请 注册新账号