Reputation: 1276
I'm working on a simple Todo App in Svelte. I recently added some edit functionality, which is a little buggy. Initially there is only an input with a submit button. Under the hood, todo is bound using bind:value
between the input value and the variable, todo.
Until I added the edit functionality, I didn't notice the bug. However, the binding between todo and the input field does not cease to exist when the submit button is clicked. I'm curious if there is a way to remove a binding as a side effect to an event?
App
<script>
import AddTodo from "./AddTodo.svelte";
import DisplayTodoItem from "./DisplayTodoItem.svelte";
let todoItems = [];
const handleTodoButtonClick = event => {
todoItems = [...todoItems, event.detail.value];
};
const handleDeleteButtonClick = event => {
todoItems = todoItems.filter(value => value != event.detail.value);
};
</script>
<style>
main {
font-family: sans-serif;
text-align: center;
}
</style>
<main>
<AddTodo on:addTodoMessage={handleTodoButtonClick}/>
{#each todoItems as item}
<DisplayTodoItem item={item} on:deleteItemMessage={handleDeleteButtonClick}/>
{/each}
</main>
AddTodo
<script>
import { createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
let todo;
</script>
<input bind:value={todo}>
<button on:click={ ()=>{dispatch('addTodoMessage', {value:todo})} }> submit </button>
DisplayTodoItem
<script>
import { createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
export let item;
let notEdit = true;
</script>
{#if notEdit}
<div style="display: inline;">
<h1> {item} </h1>
<button on:click={ () => dispatch('deleteItemMessage', {value:item} )}>
delete
</button>
<button on:click={()=> notEdit=false}> edit</button>
</div>
{:else}
<input bind:value={item}/>
<button on:click={()=> notEdit=true}> Done editing </button>
{/if}
Ideally, after clicking submit and adding a todo to the array todoItems, the binding would be removed, such that buggy behavior did not occur later when edits to todoItems occur.
Is this possible?
Upvotes: 0
Views: 288
Reputation: 184597
The item is not bound, so the changes are not saved in the list, you need:
<DisplayTodoItem bind:item .../>
Otherwise, any update will load the original value from when the item was added. It has nothing to do with the add input, that is entirely separate.
(Also, when removing items not just from the end, one should use a keyed {#each}
and the delete will remove all items with the same value. Maybe switch that to index-based if the items are primitive values.)
Upvotes: 1