javascript Stimulus JS复制元素和断开/重新连接

a0zr77ik  于 10个月前  发布在  Java
关注(0)|答案(1)|浏览(68)

我在stimulusJS中看到了一些奇怪的行为,只是在这里浏览一下教程:https://stimulus.hotwired.dev/handbook/working-with-external-resources
我开始修修补补,接近尾声时,我做了一些修改,因为指南中似乎有不一致的地方。
它现在是连接和断开连接,它console.log的重复,因为我有一个在connect方法。它还重复追加整个DOM元素。
在元素上没有循环。我停止了服务器并启动了它,不确定还有什么原因导致了它。没有错误。
x1c 0d1x的数据
Github上的来源:https://github.com/dmc2015/stimulus-starter
我正在考虑在几个项目中使用它,而不是react/vue,但如果它不可靠,不传达错误,我会通过。
控制器之一:

// src/controllers/content_loader_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static values = { url: String, refreshInterval: Number}

  connect() {
    this.load()
    // this.load_params()
    // if (this.hasRefreshIntervalValue) {
    //   this.startRefreshing()
    // }
  }

  disconnect() {
    this.stopRefreshing()
  }

  startRefreshing() {
    this.refreshTimer = setInterval(() => {
      this.load()
    }, this.refreshIntervalValue)
  }

  stopRefreshing() {
    if (this.refreshTimer) {
      clearInterval(this.refreshTimer)
    }
  }

  // load({ params }) {
  //   fetch(params.url)
  //     .then(response => response.text())
  //     .then(html => this.element.innerHTML = html)
  // }

  // loadTemplate( { params } ) {
  //   fetch(params.url)
  //     .then(response => response.text())
  //     .then(html => this.element.innerHTML = html)
  // }

  load() {
    fetch(this.urlValue)
      .then(response => response.text())
      .then(html => this.element.innerHTML = html)
  }
}

字符串
index.html

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="main.css">
    <script src="bundle.js" async></script>
  </head>
  <body>

    <!-- <div data-controller="content-loader"
      data-content-loader-url-value="/messages.html"
      data-content-loader-refresh-interval-value="5000">
      <a href="#" data-content-loader-url-param="/messages.html" data-action="content-loader#load_params">Messages</a>
      <a href="#" data-content-loader-url-param="/comments.html" data-action="content-loader#load_params">Comments</a>
    </div> -->
    <div data-controller="content-loader">
      <a href="#" data-content-loader-url-param="/messages.html" data-action="content-loader#loadTemplate">Messages</a>
      <a href="#" data-content-loader-url-param="/comments.html" data-action="content-loader#loadTemplate">Comments</a>
    </div>

    <h1 data-controller="example"></h1>

    <div data-controller="hello">
      <input data-hello-target="name" type="text">
      <button data-action="click->hello#greet">Greet</button>
    </div>

    <!-- <div data-controller="clipboard">
      PIN: <input data-clipboard-target="source" type="text" value="">
      <button data-action="click->clipboard#copy">Copy to Clipboard</button>
    </div> -->

    <div data-controller="clipboard"  data-clipboard-supported-class="clipboard--supported">
      PIN: <textarea data-clipboard-target="source" type="text" value="234"></textarea>
      <button data-action="clipboard#copy" data-clipboard--supported-class="clipboard--supported" class="clipboard-button">Copy to Clipboard</button>
    </div>

    <div data-controller="slideshow" data-slideshow-index-value="0">
      <button data-action="slideshow#previous"> ← </button>
      <button data-action="slideshow#next"> → </button>
    
      <div data-slideshow-target="slide">🐵</div>
      <div data-slideshow-target="slide">🙈</div>
      <div data-slideshow-target="slide">🙉</div>
      <div data-slideshow-target="slide">🙊</div>
    </div>
  </body>
</html>

tag5nh1u

tag5nh1u1#

基于最小可能的代码来重现您的场景(如下所示),刺激控制器正在按文档工作,但可能不像您期望的那样。

代码

这应该是生成上述输出的代码。

import { Controller } from '@hotwired/stimulus';

export default class extends Controller {
  static values = { url: String, refreshInterval: Number };

  connect() {
    this.load();
  }

  load() {
    fetch(this.urlValue)
      .then((response) => response.text())
      .then((html) => (this.element.innerHTML = html));
  }
}

个字符

说明

1.默认值来自getters

this.[some]value getters的文档中,当你没有声明一个值时,你将得到默认值。字符串的默认值是空字符串。
这意味着没有设置data-content-loader-url-value的HTML <div data-controller="content-loader">将默认为''(空字符串)。

2. connect回调

一旦你的控制器连接上了,connect回调就会运行,这反过来又会调用你的this.load方法。
load方法将对urlValue发出一个fetch请求,该请求将是一个空字符串,在使用fetch时默认为当前URL。

3. innerHTML更新

一旦fetch解析,它将拉入当前页面的完整HTML,包括<div data-controller="content-loader"> HTML的另一个副本。这将在“content-loader”中创建另一个动态加载的受控元素。
这将调用该示例的connect/load方法,然后重复该循环。

解决方案

要解决这个问题,请记住考虑您的控制器的值,以及如果没有提供它们的默认值。
您甚至可以有意在这里设置一个默认值,如果没有提供该值,您可以使用该默认值。参见https://stimulus.hotwired.dev/reference/values#default-values

export default class extends Controller {
  static values = {
    url: { default: '/path/to/content', type: String },
    refreshInterval: Number,
  };
// ...


关于你对文档的问题:
……因为看起来指南里有不一致的地方。
如果能理解这里的具体问题就太好了,文档中关于使用应该是fixed in a future release的值的措辞有些混乱,但可能还需要更多的工作。
至于错误处理;
但如果它不可靠,不传达错误,我会通过。
我认为,在下结论之前,最好先了解一下“刺激”是如何解决错误的。在这个场景中,没有错误,但很高兴知道Stimulus将运行try/catch中的所有方法,并且实际上非常擅长记录错误。它类似于每个Controller示例上的React边界,但默认情况下包含。
然而,当使用Promise时,需要应用与React/Vue相同的考虑因素。您需要使用catch或async/try/catch来捕获可能异步发生的错误。
您可以在文档中阅读更多关于Stimulus错误处理的信息。

相关问题