I have used Vue.js extensively in the past so this pattern may not translate well to svelte, I understand that.
My question is why doesn't the following work in svelte and what is the correct pattern to use.
When I click on the edit button, It works as expected, but when I click save it doesn't revert back to main component. The values seem to be updated but the component doesn't refresh.
<script>
import Editing from './editing.svelte';
let data = true;
let editing = false;
let editingSection;
function startEditing(section) {
editingSection = section;
editing = true;
}
function doneEditing() {
editing = false;
editingSection = '';
}
</script>
<div>
{#if data && !editing}
<div>
Yes we have data!
<button on:click={startEditing("main")}>Edit</button>
</div>
{/if}
<!-- Are we in editing mode -->
{#if editing}
<Editing section={editingSection} on:done-editing={doneEditing}/>
{/if}
</div>
<script>
import { createEventDispatcher } from 'svelte';
export let section = null;
const dispatch = createEventDispatcher();
function save() {
dispatch('done-editing');
}
</script>
<div>
Editing Section {section}
<button on:click={save}>Save</button>
</div>
I have even tried the $: to make the statements reactive. Doesn't work
Svelte Version: 3.34.0
SvelteKit
Your mistake is that <button on:click={startEditing('main')}>
does not do what you expect it to do. It will during render execute the startEditing
function and add the return value of this function as a listener to the click event.
The correct syntax would be: <button on:click={() => startEditing('main')}>
as you see here, the handler is a function.
In the other event handler: <Editing on:done-editig={doneEditing}>
you are correctly passing a function.