Прослушивание отправленного события из компонента Svelte

Я ищу способ прослушивать отправленное событие из компонента Svelte в другом компоненте из JavaScript (а не из синтаксиса on:).

Вот код, который я пытаюсь достичь в REPL.

Ожидаемым поведением будет отображение 0 в консоли при нажатии кнопки Закрыть 0 и т. Д. Для других кнопок.


person mlbiche    schedule 27.04.2020    source источник


Ответы (1)


Я немного покопался в скомпилированном коде svelte и нашел решение для прослушивания обработанного события svelte, но это некрасиво :)

Вы можете (и должны) отправлять свое собственное событие при вызове onClose, но вот решение:

на Nested.svelte

<script context="module">
    let counter = 0
</script>

<script>
    import { createEventDispatcher, onMount } from 'svelte';
    // add this
    import { get_current_component } from 'svelte/internal'; 
    let _this;
    const id = counter++
  const dispatch = createEventDispatcher()
    /*********
     and add this reactive statement
    **********/
    $: {
        if (_this){
            _this.parentNode.hosts = (_this.parentNode.hosts || []);
            _this.parentNode.hosts.push(get_current_component());
        }
    } 
    /*********
     end
    **********/
    function onClose() {
        dispatch('close', id)
    }
</script>
<!-- bind this -->
<button bind:this={_this} class='nested-button' on:click={onClose}>
    Close {id}
</button>

Затем в вашем App.svelte

<script>
    import { onMount } from 'svelte'
    import Nested from './Nested.svelte'

    let element

    onMount(() => {
        // requestAnimationFrame is required!
        requestAnimationFrame(() => element.hosts.forEach(nestedButton => {
        nestedButton.$on('close', (e) => {
                console.log(e.detail)
            })
        }));
    })
</script>

<ul bind:this={element}>
    <Nested/>
    <Nested  />
    <Nested />
</ul>

Объяснение -

единственный способ привязаться к svelte-событию - получить ссылку на вызывающий компонент и вызвать метод $on, но в настоящее время нет простого способа получить ссылку на компонент.

поэтому я вызвал внутреннюю функцию svelte get_current_component, которая вернет текущий компонент (но по какой-то причине не будет работать при вызове внутри onMount).

Я добавил ссылку на parentNode.hosts самого верхнего элемента в компоненте, которым в данном случае является элемент ul.

тогда вы можете просто вызвать метод $on для каждой ссылки в element.hosts.

Однако подходящее решение будет отправлять вам собственное событие следующим образом:

function onClose() {
        dispatch('close', id)
        this.dispatchEvent(new CustomEvent('close', {detail: id}));
    }

И этим достигается почти то же самое, не беспокоясь о внутренностях svelte.

person Hagai Wild    schedule 27.04.2020
comment
Спасибо за полный ответ и за хитрый обходной путь. Я проверю это, но да, похоже, что svelte не предназначен для того, чтобы улавливать события его компонентов ... - person mlbiche; 28.04.2020