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

Wix自定义元素:如何在connectedCallback后触发聊天历史加载事件?

解决方案:Wix Custom Element 自动加载聊天历史记录

核心思路

由于仅能在页面代码中调用 Velo API 读取存储,需确保页面代码读取数据和Custom Element 挂载渲染的顺序对齐:要么页面代码主动将数据推送给已挂载的 Custom Element,要么让 Custom Element 挂载后主动触发页面代码拉取数据(需修复事件穿透问题)。

方案一:页面代码主动推送数据(推荐)

利用 $w.onReady() 确保页面就绪后读取存储,延迟片刻确保 Custom Element 已挂载到 DOM,再通过属性传递聊天记录。

页面代码(Velo)

$w.onReady(async function () {
  // 1. 调用 Velo API 读取用户聊天历史
  const chatRecords = await wixData.query("ChatHistory")
    .eq("userId", wixUsers.currentUser.id)
    .ascending("createdAt")
    .find();

  // 2. 延迟确保 Custom Element 已挂载到 DOM
  setTimeout(() => {
    const chatElement = $w("#yourCustomElementId");
    // 将历史记录转为 JSON 字符串,通过属性传递
    chatElement.setAttribute("chat-history", JSON.stringify(chatRecords.items));
  }, 300); // 根据实际加载速度调整延迟时长
});

Custom Element 代码

class ChatElement extends HTMLElement {
  // 监听 chat-history 属性变化
  static get observedAttributes() {
    return ["chat-history"];
  }

  connectedCallback() {
    // 元素挂载后,先检查是否已有历史记录属性
    const historyData = this.getAttribute("chat-history");
    if (historyData) {
      this.renderHistory(JSON.parse(historyData));
    }
  }

  attributeChangedCallback(name, oldVal, newVal) {
    if (name === "chat-history" && newVal) {
      this.renderHistory(JSON.parse(newVal));
    }
  }

  // 渲染聊天历史的核心逻辑
  renderHistory(history) {
    const chatContainer = this.querySelector(".chat-messages");
    chatContainer.innerHTML = ""; // 清空原有内容

    history.forEach(msg => {
      const msgEl = document.createElement("div");
      msgEl.className = msg.senderId === wixUsers.currentUser.id ? "my-message" : "other-message";
      msgEl.textContent = `${msg.senderName}: ${msg.content}`;
      chatContainer.appendChild(msgEl);
    });
  }
}

customElements.define("chat-element", ChatElement);

方案二:修复 Custom Element 事件触发问题

若坚持用事件触发页面代码拉取数据,需确保事件能穿透 Shadow DOM(如果使用了 Shadow DOM),页面代码提前监听事件。

页面代码(Velo)

$w.onReady(function () {
  const chatElement = $w("#yourCustomElementId");
  // 提前监听 Custom Element 派发的事件
  chatElement.addEventListener("load-history", async () => {
    const chatRecords = await wixData.query("ChatHistory")
      .eq("userId", wixUsers.currentUser.id)
      .ascending("createdAt")
      .find();
    chatElement.setAttribute("chat-history", JSON.stringify(chatRecords.items));
  });
});

Custom Element 代码

class ChatElement extends HTMLElement {
  connectedCallback() {
    // 派发事件时必须加上 bubbles: true 和 composed: true,确保事件能被页面代码捕获
    this.dispatchEvent(new CustomEvent("load-history", {
      bubbles: true,
      composed: true
    }));
  }

  // 同方案一的 attributeChangedCallback 和 renderHistory 逻辑
  static get observedAttributes() { return ["chat-history"]; }
  attributeChangedCallback(name, oldVal, newVal) {
    if (name === "chat-history" && newVal) {
      this.renderHistory(JSON.parse(newVal));
    }
  }
  renderHistory(history) { /* ... */ }
}

customElements.define("chat-element", ChatElement);

关键注意事项

  • 不要依赖 attributeChangedCallback 在元素未挂载时渲染:此时元素还未加入 DOM,操作节点不会生效。
  • 事件派发必须配置 bubbles: true 和 composed: true:否则 Custom Element 内部的事件无法穿透到页面代码层面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 16:22:22