ruby-on-rails 如何知道Turbo.renderStreamMessage何时完成?

qacovj5a  于 2023-04-08  发布在  Ruby
关注(0)|答案(1)|浏览(167)

我正在填充一个空列表对象

<ul id="results"></ul>

通过Turbostream请求

# myaction.turbo_stream.erb 
<%= turbo_stream.append "results" do %>
    <li data-mystimulus_target="item">HELLO WORLD</li>
<% end %>

我通过fetch API从一个刺激控制器发出请求,我想在新的item目标被附加到DOM后与它们交互。

// mystimulus_controller.js
static targets = ["item"]

connect() {
    fetch(this.myRequest())
        .then(response => {
            if (response.ok) {
                return response.text()
            }
            throw response.status
        })
        .then(html => { 
            Turbo.renderStreamMessage(html)
            // immediate
            console.log("immediate has items check", this.hasItemTarget))
            // delayed
            this.delay(1000).
                then(() => console.log("delayed has items check", this.hasItemTarget))
        
            })
        .catch(error => console.warn(error))
} 

myRequest() {
    return new Request("myurl", {
        method: "GET",
        headers: {
            Accept: "text/vnd.turbo-stream.html"
        },
        redirect: "manual"
    });
}

delay(milliseconds){
    return new Promise(resolve => {
        setTimeout(resolve, milliseconds);
    });
}

console.log("immediate has items check", this.hasItemTarget))返回false
console.log("delayed has items check", this.hasItemTarget))返回true
Turbo.renderStreamMessage看起来是异步的,但是在深入研究之后,我没有发现这个函数公开的任何回调或promise。
有没有更好的方法来确保Turbo.renderStreamMessage在继续之前已经完成(我想摆脱我的delay()函数)。

eblbsuwk

eblbsuwk1#

这里的Turbo流只做了一个简单的append,如果你想做一些更复杂的事情,也许自定义turbo流操作会是一个更好的选择:

  • https:turbo.hotwired.dev/handbook/streams#custom-actions*

您可以使用刺激目标回调来了解何时插入元素:

<li data-mystimulus-target="item">HELLO WORLD</li>
                   ^

添加到刺激控制器:

itemTargetConnected(target) {
  console.log(target);
}
  • https:stimulus.hotwired.dev/reference/targets#connected-and-disconnected-callbacks*

您可以随时添加自己的观察者:

connect() {
  this.observer = new MutationObserver((mutationList) => {
    mutationList.forEach((mutation) => {
      if (mutation.type == "childList") {
        mutation.addedNodes.forEach((node) => {
          if (node instanceof Element) {
            console.log(node);
          }
        });
      }
    });
  });
  this.observer.observe(this.element, { childList: true });
}

disconnect() {
  this.observer.disconnect();
}

https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
此外,不要低估涡轮增压框架,它可以为您做一些工作:

<%= turbo_frame_tag :results, data: {controller: :mystimulus} %>

最好在请求位置有一个匹配的turbo-frame,但这样也可以:

connect() {
  this.element.src = "/myurl.turbo_stream"
}

只是不要做得太过:

connect() {
  this.element.loaded
    .then(() => {
      this.element.src = "/items/1.turbo_stream";
      return this.element.loaded;
    })
    .then(() => {
      this.element.src = "/items/2.turbo_stream";
      return this.element.loaded;
    })
    .then(() => {
      this.element.src = "/items/3.turbo_stream";
    });
}
  • https:turbo.hotwired.dev/reference/frames#properties*

相关问题