承诺更新 DOM 后如何获得钩子

How can I get a hook after a promise update the DOM

我有一个代码要维护,它与它类似:

{#await details}
    {#each values as value, i}
        <td id="{`${config.id}_${i}`}">{value}</td>
    {/each}
{:then details_result}
    {#each details_result as detail, i}
        <td id="{`${config.id}_${i}`}" class:detail="{detail.class}">{detail.value}</td>
    {/each}
{/await}

我必须使用 jQuery (bootstrap popovers) 将一些事件绑定到这个 <td> 并且当我应该调用这个事件绑定时我遇到了一些问题,主要是因为 Svelte 删除了<td>#await 中,一旦 :then 被调用,然后将旧 <td> 放置在新 <td> 中。


首先,我尝试在 Svelte afterUpdate 函数中绑定此事件。它的问题是这个函数只在 #await <td> 放置之后被调用。 :then <td> 放置不触发 afterUpdate.

afterUpdate(() => {
    values.forEach((value, i) => { $(`#${config.id}_${i}`).popover(); });
})

其次,我尝试将此事件绑定到 details 承诺的 then() onFulfilled 函数中,但是尽管我在承诺得到解决后调用事件绑定,但 Svelte 不会更新 DOM 和新的 <td>,然后我仍然绑定旧的 <td> 中的事件。

$: details = (...) => {
    [...]
    return new Promise(...).then(() => {
        values.forEach((value, i) => { $(`#${config.id}_${i}`).popover(); });
        [...]
    });
}();

如何在插入 Svelts 的 :then 中的 <td> 后得到一个 callback/hook?或者,我可以选择如何强制 Svelte 保留 <td> HTML 元素引用?

好吧,您可以使用 bind:this 指令获取对 DOM 元素的引用,但是随着列表的变化,跟踪创建和销毁的元素需要大量的簿记工作。

对于你想要的,你可能应该使用 action。它将自定义函数附加到 DOM 元素生命周期。该函数在创建元素时被调用,您还可以提供在元素被销毁时调用的清理函数。

看起来像这样:

<script>
  export let items = []

  const openPopover = el => { ... }

  // this is the action function
  const popover = el => {

    // do magic with DOM element
    el.addEventListener('click', openPopover)

    const destroy = () => {
      // cleanup if you need
      el.removeEventListener('click', openPopover)
    }

    return { destroy }
  }
</script>

{#each item of items}
  <!-- our function will be called for every td element -->
  <td use:popover>
    {item.name}
  </td>
{/each}