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.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With