在 HTML 自定义元素中使用外部数据

问题描述 投票:0回答:1

我正在创建一个与 Vite 捆绑在一起的简单网站,但没有像 React、Vue、Svelte 等外部框架。该网站具有使用不同数据的重复 HTML 元素。我想为此使用自定义元素。我使用自定义元素而不是完整的 Web 组件,因为我希望能够使用全局样式表。数据位于外部 JSON 文件中。我遇到了计时问题,这些问题导致难以及时将数据获取到自定义元素以便对其进行配置。

我的 HTML 看起来像:

<!doctype html>
<html lang="en">
  <head>...</head>
  <body>
    <main>
      <my-element data-content-id="0"></my-element>
      <another-element data-content-id="1"></another-element>
      <my-element data-content-id="2"></my-element>
      <another-element data-content-id="3"></another-element>
    </main>
    <script type="module" src="/main.js"></script>
  </body>
</html>

main.js:

import MyElement from "./custom-elements/MyElement.js"
import AnotherElement from "./custom-elements/AnotherElement.js"

const init = () => {

  // load external config
  const configFile = "/config.json"

  fetch(configFile)
    .then(config => config.json())
    .then(config => {
       console.log("[Main] app initiated in main.js")
       const myElement = new MyElement(config)
       const anotherElement = new AnotherElement(config)
      }
    })
    .catch(error => console.error('Error:', error))
}

init()

MyElement.js:

class MyElement extends HTMLElement {
    constructor(config) {
        super()
        this.config = config
        console.log("constructor")

        if (this.config) {
            console.log("calling useData from constructor", this.config)
            this.useData(this.config)
        }
    }

    useData(prop) {
        console.log("useData")
        // ... logic here ...
    }

    connectedCallback() {  
        console.log("connected callback")
        if (this.config) {
            console.log("calling useData from callback", this.config)
            this.useData(this.config)
        }

        this.innerHTML = `
            <div>
                ...
            </div>
        `;
      }
}

window.customElements.define('my-element', MyElement)

export default MyElement;

当我查看日志时,我发现

constructor
connected callback
记录在
[Main] app initiated in main.js
之前。然后,当实例化 MyElement 类时,再次调用/记录
constructor
,这次带有数据,因此
useData
运行/记录。但此时,我已经运行了构造函数两次,并且无法访问 DOM 中的自定义元素来使用数据。

所以,总而言之,即使我在数据加载之前没有实例化

main.js
中的类,构造函数也会被调用两次:一次是当自定义元素出现在 DOM 中时(我猜,无论如何,它是在获取数据之前),以及使用数据实例化时(在获取数据之后)一次。加载数据并实例化类后,我将无法访问通过
connectedCallback
获得的自定义元素。

有没有办法在自定义元素中使用外部获取的数据并正确计时?

javascript json fetch-api web-component custom-element
1个回答
0
投票
    <main>
      <my-element data-content-id="0"></my-element>
      <another-element data-content-id="1"></another-element>
      <my-element data-content-id="2"></my-element>
      <another-element data-content-id="3"></another-element>
    </main>
    <script type="module" src="/main.js"></script>

您在 DOM 中的 Web 组件被解析之后加载脚本。 因此 constructor

connectedCallback
(在 
opening 标签上触发)已经运行。

您现在有了一个全局

init()

,它
告诉?您的组件要做什么?

也许反转逻辑,让Web组件

加载数据(可以记忆)

您可以通过添加

最小可重现示例 StackOverflow Snippet 来帮助我们回答您的问题。它将帮助读者一键执行您的代码。并一键帮助创建答案。

© www.soinside.com 2019 - 2024. All rights reserved.