Пользовательский элемент Svelte не передает события - PullRequest
1 голос
/ 06 марта 2020

Я хочу использовать Tabulator в моем проекте, который еще не имеет интеграции с Svelte. Это очень полная библиотека таблиц данных, которую я уже использовал ранее. Но когда я пытался создать типичный столбец с кнопками действий (редактировать, удалять ...), я всегда использовал их Пользовательские форматеры , которые возвращают html в виде строки.

Функция который форматирует столбец, возвращает что-то вроде этого:

return '<ul class="actions_row"><li><custom-button on:click={handleClick}>Edit</custom-button></li></ul>';

<custom-button /> - это пользовательский элемент, созданный с использованием <svelte:options> и добавленный в проект с помощью index. html (<script src="lib/CustomButton.js"></script>).

Пользовательская кнопка показана в таблице, но она не может пересылать события . Кажется, что компонент не может обмениваться данными вне своей области видимости.

Ответы [ 2 ]

1 голос
/ 06 марта 2020

Строка, возвращаемая вашим пользовательским форматером, будет обрабатываться как "нормальная" HTML, поэтому синтаксис Svelte больше не доступен ... А именно on:click является синтаксисом Svelte и не будет обрабатываться браузером.

Я не эксперт по пользовательским элементам, но, к сожалению, по мнению других , то, что вы пытаетесь сделать, невозможно. То есть вы не можете зарегистрировать прослушиватели пользовательских событий только на пользовательских элементах HTML. Вам обязательно придется сделать это с JS. Примерно так:

    <script>
      document.querySelector('custom-button')
        .addEventListener('my-event', e => {
          console.log(e.detail)
        })
    </script>

Кроме того, имейте в виду, что события от пользовательских элементов в Svelte в настоящее время имеют некоторые ограничения (см. эту проблему ).

Итак, чтобы иметь собственные события для ваших пользовательских элементов, вам придется использовать какой-то обходной путь. Например, вот компонент, который запускает прослушиватель в приведенном выше фрагменте кода:

<svelte:options tag="custom-button" />

<script>
  import { onMount } from 'svelte';

  let el

  onMount(() => {
    const interval = setInterval(() => {
      let event = new CustomEvent('my-event', {
          detail: {time: Date.now()},
          bubbles: true,
          composed: true, // needed for the event to traverse beyond shadow dom
      })
      el.dispatchEvent(event)
    }, 1000)

    return () => {
      clearInterval(interval)
    }
  })
</script>

<button bind:this={el}><slot /></button>

Обратите внимание, что такой код будет иметь ограниченную поддержку со старыми браузерами.

Все это, как говорится, только для точно так же, как в вашем примере, вы, очевидно, могли бы заставить его работать, зарегистрировав свое событие в собственном браузере onclick вместо Svelte on:click. Я все еще не эксперт по CE, но я предполагаю, что браузер обрабатывает стандартные события, которые доступны для всех встроенных элементов, таких как нажатие или нажатие клавиши на элементах CE тоже ...

Итак, похоже, это должно работать для вас :

return '<ul class="actions_row"><li><custom-button onclick="handleClick">Edit</custom-button></li></ul>';

Примечание: onclick="handleClick" вместо on:click={handleClick}. Теперь вы находитесь в стандартной браузерной стране, поэтому применяются обычные правила, так же, как если бы вы использовали обычный <button> ... handleClick, который должен быть доступен в области видимости, и т. Д. c.

0 голосов
/ 10 апреля 2020

Причина, по которой это происходит, заключается в том, что вы возвращаете строку HTML из средства форматирования, что означает, что любые привязки JS, такие как обработчики событий click, будут удалены как часть преобразования ее в строку. (контекст привязки функции щелчка будет утерян, так как функция будет действительна только в функции, в которой строка была записана не там, где она была проанализирована)

Чтобы сохранить привязки, вы должны вернуть Объект узла , представляющий кнопку, а не только ее HTML, таким образом любые привязки событий, добавленные к ней вашей другой библиотекой останется нетронутым.

...