I have a series of 3 Svelte components, one inside the other, and am trying to forward an event from the innermost to the outermost component. However, the event is only triggered on the second, middle component, and is never triggered on the outermost.
Innermost (TreeNodeView.svelte
)
<script lang="ts">
import { createEventDispatcher } from "svelte";
import TreeNode from "./TreeNode";
import TreeView from "./TreeView.svelte";
const dispatch = createEventDispatcher();
function onWantsUpload() {
console.log("TreeNodeView");
dispatch("wantsUpload", treeNode.id);
}
export let treeNode: TreeNode;
</script>
<li>
</span>
<span class="upload"
aria-label={`Upload new version: ${treeNode.text}`}
role="button"
on:click={onWantsUpload}
on:keyup={onWantsUpload}>
<Upload title={`Upload new version: ${treeNode.text}`} />
</span>
</li>
Middle (TreeView.svelte
)
<script lang="ts">
import TreeNode from "./TreeNode";
import TreeNodeView from "./TreeNodeView.svelte";
export let treeNodes: Array<TreeNode>;
</script>
<ul role="group">
{#each treeNodes as treeNode ( treeNode.id )}
<TreeNodeView
{treeNode}
on:wantsUpload />
{/each}
</ul>
Outermost (ProjectDetail.svelte
)
<script lang="ts">
import ProjectDetailModel from "../../../models/ProjectDetail";
import TreeNode from "../treeView/TreeNode";
import TreeView from "../treeView/TreeView.svelte";
export let treeNodes: Array<TreeNode>;
export let projectDetail: ProjectDetailModel;
function onWantsUpload(e: CustomEvent<string>) {
console.log("ProjectDetail");
}
</script>
<TreeView
{treeNodes}
on:wantsUpload={onWantsUpload} />
When I click the Upload element on the innermost component, I expect in the console to see …
TreeNodeView
ProjectDetail
… but all I see is …
TreeNodeView
To debug, I’ve modified the middle component (TreeView.svelte
) to explicitly handle and then re-dispatch the event:
<script lang="ts">
import { createEventDispatcher } from "svelte";
import TreeNode from "./TreeNode";
import TreeNodeView from "./TreeNodeView.svelte";
const dispatch = createEventDispatcher();
export let treeNodes: Array<TreeNode>;
function onWantsUpload(e: CustomEvent<string>) {
console.log("TreeView");
dispatch("wantsUpload", e.detail);
}
</script>
<ul role="group">
{#each treeNodes as treeNode ( treeNode.id )}
<TreeNodeView
{treeNode}
on:wantsUpload={onWantsUpload} />
{/each}
</ul>
And now, when I click the Upload element on the innermost component, I expect in the console to see …
TreeNodeView
TreeView
ProjectDetail
… but all I see is …
TreeNodeView
TreeView
What have I missed? Why is my outermost component not receiving the event, or why is the middle component not dispatching the event?