Best viewed on desktop Mobile Friendly tutorial coming soon!
Add, Toggle, Remove
Now the behaviour — and the second communication channel. Data goes
down on input; a child talks back up by calling a function
the parent passed. Marko has no emit — you hand the child a callback
and it calls it:
<!-- parent --><todo-item todo=todo onDelete() { todos = todos.filter((t) => t.id !== todo.id) }/>
<!-- child --><button onClick() { input.onDelete() }>Delete</button>The parent owns the list, so every change is the same move you learned
for arrays — build a new array and assign it: filter to delete,
map with a spread to toggle one item’s done, spread to add.
Wire it up:
- Make
todosa<let>, add a<let/draft="">for the input, and bind the input withvalue:=draft. - Add an Add button that appends a new todo —
todos = [...todos, { id: Date.now(), text: draft.trim(), done: false }]— and clears the draft. - Pass
onToggleandonDeletehandlers to each<todo-item>; in the child, callinput.onToggle()from the checkbox’sonChangeandinput.onDelete()from the button. - Derive the count —
<const/remaining=...>over the undone todos — and make Clear completed drop the done ones.
Add, check off, delete — a working list. One channel down, one up.
Files
Preparing Environment
- Installing dependencies
- Starting dev server