0
votes

I wanted to create a component that exposes a function in the parent. While the Svelte docs point to context="module", that script gets called only once, which would break functionality if I have several instances of the same component.

I found several examples on the internet and they all point to a very handy workaround, defining the export in the component and calling it with dot notation:

// Child.svelte

<script>
        let element
        export function changeColor() {
        console.log(element)
        element.style.backgroundColor = "#" + Math.floor(Math.random() * 16777215).toString(16)
}
</script>

<button bind:this={element}>A button</button> 

I created a very simple use case, which works when I bind the component to a variable and call it with child.function, but what if I want to call the function from a click on the component itself?

// App.svelte
<script>
    import Child from "./Child.svelte"
    let child
    
</script>
 
<button on:click={() => child.changeColor()}>Click</button>        // This works
<Child bind:this={child} on:click={() => child.changeColor()} />   // This doesn't work 

I understand the logic behind the first option, however I don't understand why the second option doesn't work! Should it be the same? I binded the component to a variable, and I am calling it with the same syntax. How can i make it work, without using a second element that calls the function?

1

1 Answers

0
votes
<Child bind:this={child} on:click={() => child.changeColor()} /> 

doesn't work because on:click is not defined, you can easily see this when changing it to on:click={() => console.log('test')}

The reason it doesn't work is because in Svelte events do not 'bubble' out of components, if you want to do that you have to explicitly indicate this in Child.svelte

<button bind:this={element} on:click>A button</button>