Passing on:click event into dynamically created <svelte:component/>

心不动则不痛 提交于 2019-12-08 04:37:33

问题


I basically need to be able to trigger something within one or more components (that are being dynamically added via svelte:component) when an icon/button within the parent component is clicked. e.g. I need to hook the parts denoted with ** below:-

<script>
 let charts = [
    ChartA,
    ChartB,
    ChartC
  ];
</script>
{#each charts as chart, i}
    <div class="wrapper">
        <div class="icon" on:click={**HowToPassClickEventToComponent**}></div>
        <div class="content">
        <svelte:component this={charts[i]} {**clickedEvent**}/>
        </div>
    </div>
{/each}

I was able to get something working by unsing an array of props but each component is notified when the array changes so this is not very clean.

I have searched both Google and StackOverflow as well as asking this question within the Svelte Discord channel with currently no luck.

Svelte Repl showing the problem

This seems like such a simple requirement but after a couple of days I remain stuck so any advice on how to pass events into dynamic components is much appreciated.


回答1:


You could do it like this:

<script>
    import ChartA from './ChartA.svelte'
    import ChartB from './ChartB.svelte'
    import ChartC from './ChartC.svelte'
    let charts = [
        ChartA,
        ChartB,
        ChartC
    ];
    let events = [];
</script>

<style>
    .icon{
        width:60px;
        height:30px;
        background-color:grey;
    }
</style>

{#each charts as chart, i}
    <div class="wrapper">
        <div class="icon" on:click={e=>events[i] = e}>Click</div>
        <div class="content">
            <svelte:component this={charts[i]} event={events[i]}/>
        </div>
    </div>
{/each}

Passing events around as data would be a bit unusual though. It would be more idiomatic to set some state in the parent component in response to the event, and pass that state down.

Alternatively, if the child components do need to respond to events themselves you could take this approach...

<script>
    import ChartA from './ChartA.svelte'
    import ChartB from './ChartB.svelte'
    import ChartC from './ChartC.svelte'
    let charts = [
        ChartA,
        ChartB,
        ChartC
    ];
    let instances = []; 
</script>

<style>
    .icon{
        width:60px;
        height:30px;
        background-color:grey;
    }
</style>

{#each charts as chart, i}
    <div class="wrapper">
        <div class="icon" on:click={e => instances[i].handle(e)}>Click</div>
        <div class="content">
            <svelte:component
                this={charts[i]}
                bind:this={instances[i]}
            />
        </div>
    </div>
{/each}

...where each child component exports a handle method:

<script>
    let event;
    export function handle(e){
        event = e;
    };
</script>


来源:https://stackoverflow.com/questions/58110067/passing-onclick-event-into-dynamically-created-sveltecomponent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!