Как я могу получить хук после обещания обновить DOM - PullRequest
1 голос
/ 11 февраля 2020

У меня есть код для поддержки, и он похож на него:

{#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}

Мне нужно привязать некоторые события к этому <td> с jQuery (bootstrap popovers ) и у меня возникают некоторые проблемы, когда я должен вызывать эту привязку события, главным образом потому, что Svelte удаляет <td> внутри #await, когда вызывается :then, а затем помещает старый <td> новым.


Сначала я попытался связать это событие внутри функции Svelte afterUpdate. Проблема в том, что эта функция вызывается только после размещения #await <td>. :then <td> размещение не срабатывает afterUpdate.

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

Во-вторых, я пытался связать это событие с функцией then() onFulfilled обещания details, но, несмотря на то, что я ' Я вызываю привязку события после того, как обещание было выполнено, Svelte не обновляет DOM с новым <td>, тогда я все еще связываю событие в старом <td>.

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

Как можно У меня есть обратный вызов / ловушка после вставки <td> от Svelts :then? Или, как вариант, как заставить Svelte сохранить ссылку на элемент <td> HTML?

1 Ответ

2 голосов
/ 11 февраля 2020

Ну, вы можете получить ссылки на элементы DOM с помощью директивы bind:this, но это будет большая бухгалтерия для отслеживания созданных и уничтоженных элементов при изменении списка.

Для чего вы хотите, вероятно, вы должны использовать действие . Он прикрепляет пользовательскую функцию к жизненному циклу элементов 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}
...