Svelte v3 программно создает компонент с подпорками и слушателями событий - PullRequest
0 голосов
/ 14 февраля 2020

Можно ли создать компонент и программно подключить к нему прослушиватели событий?

Я знаю, что это легко возможно для реквизита, использующего <svelte:component/>, с расширением { ...props }. Интересно, можно ли добиться чего-то подобного для присоединения слушателей событий.

Например, в следующем примере я хотел бы программно присоединить on:message к A и on:count к B:

<!-- App.svelte -->
<script>
    import A from './A.svelte';
    import B from './B.svelte';

    let message = 'Hi there ?';
    let count = 0;

    const components = [{
        component: A,
        props: { message },
        listeners: { message: (m) => { console.log(`They say "${m}"`); } }
    }, {
        component: B,
        props: { count },
        listeners: { click: () => { count++; } }
    }];
</script>

{#each components as component}
    <div><svelte:component this={component.component} { ...component.props }/></div>
{/each}

<div>
    <p>They say "{message}"!</p>
    <p>They clicked {count} times!</p>
</div>

<!-- A.svelte -->
<script>
    import { createEventDispatcher } from 'svelte';
    const dispatch = createEventDispatcher();
    export let message = '';
    function changeHandler(e) { dispatch('message', message); }
</script>

<input on:change={changeHandler} on:value={message} value={message} />

<!-- B.svelte -->
<script>
    import { createEventDispatcher } from 'svelte';
    const dispatch = createEventDispatcher();
    export let count = 0;
    function clickHandler() { dispatch('count', count); }
</script>

<button on:click={clickHandler}>Click me</button>

Вот демонстрационная версия: https://svelte.dev/repl/af1bd30ab75b43f19b72a306340b7282?version=3.18.2

То есть, я надеюсь, что есть способ расширить массив components до

<A message={message} on:message={e => { message = e.detail; }}/>
<B count={count} on:count={e => { count = e.detail; }}/>

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

Вы не можете динамически присоединять слушателей, нет - не забывайте, что Svelte - это скомпилированный язык, он выполняет всю тяжелую работу во время компиляции, поэтому о вещах нужно знать заранее.

Что я Для динамических c прослушивателей сделано только одно известное событие, а затем детали события содержат дифференциальные логики c, такие как имена событий и т. д. c. Как в следующем:

// SomeComponent.svelte
<script>
  import { createEventDispatcher } from 'svelte'

  const dispatch = createEventDispatcher()

  dispatch('component-event', { name: 'alert', value: 'oh noes' })
  dispatch('component-event', { name: 'log', value: 'some message' })
</script>
// App.svelte
<svelte:component this={someComponent} on:component-event={e => handleEvent(e)} />

<script>
  function handleEvent ({ detail }) {
    const { name, value } = detail
    if (name === 'alert') { alert(value) }
    if (name === 'log') { console.log(value) }
  }
</script>
0 голосов
/ 16 февраля 2020

Не уверен, что вы можете программно прикрепить их так, как вы ищете, но вы можете передать функцию или обратный вызов в объекте и учесть каждое из возможных отправленных событий в теге svelte: component, например:

<svelte:component
    this={component.component}
    { ...component.props }
    on:message={ component.function}
    on:count={ component.function}
/>

Вот рабочий пример в REPL , который показывает как функцию стрелки в объекте, так и обратный вызов (если требуется более мясистая функция), обратный вызов по-прежнему получает подробности события.

Я не думаю, что что-то случится, если отправленное событие отсутствует в компоненте, но если вам нужен один компонент для отправки нескольких событий, вам нужно что-то еще.

...