skip to Main Content

For nested Svlete components, where an Outer contains several Inners, is it possible to create a dispatcher with createEventDispatcher in Inner that would communicate the instance that called the dispatcher?

Outer.svelte would look something like

<script lang="ts">
  import Inner from "./Inner.svelte";

  /* placeholder array of 0-10 elements, to make it clear the number of Inners
   * in this component is different depedning on some outside factors */
  let dynamicContent = Array.from({length: Math.random() * 10}, () => "something");

  // How is it possible to set this?
  let lastSelectedInner: Inner | null = null;
</script>

{#each dynamicContent as item}
  <Inner on:select={(event) => lastSelectedInner = event.detail} />
{/each}

And Inner.svelte would look something like:

<script lang="ts>
  import { createEventDispatcher } from "svelte";
  const dispatch = createEventDispatcher();
</script>

<button on:click={() => dispatch("select", /* how do I forward the instance here? */)} >
  <p>Click me</p>
</button>

Note: I need the actual instance to be in a variable, and not an index. Also, I don’t want to have an array of all Inners, just a single reference to a single component.

2

Answers


  1. From your comment, it sounds like the parent component instance doesn’t actually need to access the child component instance, only (some of) the data in the child component instance. So the child component instance can pass along that data in the event, and not the component instance itself. And maybe passing along data is not needed at all?

    Outher.svelte

    <script lang="ts">
      import Inner from "./Inner.svelte";
      
      
      let items = [{
        id: 1,
        name: `a`,
      }, {
        id: 2,
        name: `b`,
      }]
    
      let selectedItem: Object | null = null; // I don't know TS, so unsure about type ^^'
    
    </script>
    
    {#each items as item}
      <Inner on:select={(event) => selectedItem = item} />
    {/each}
    
    {#if selectedItem}
      <h1>Selected</h1>
      <div>Id: {selectedItem.id}</div>
      <div>Name: {selectedItem.name}</div>
    {/if}
    
    Login or Signup to reply.
  2. As far as I know the child component can’t access a reference to itself but it would have to be created via bind:this in the parent and passed as a prop.

    This would be a way to set lastSelectedInner without adding additional logic to the Inner component

    <script>
      import Inner from "./Inner.svelte";
    
      /* placeholder array of 0-10 elements, to make it clear the number of Inners
       * in this component is different depedning on some outside factors */
      let dynamicContent = Array.from({length: Math.random() * 10}, () => "something");
    
        let innerRefs = []
        
      // How is it possible to set this?
      let lastSelectedInner = null;
        $: console.log(lastSelectedInner)   
    </script>
    
    {#each dynamicContent as item, index}
      <Inner bind:this={innerRefs[index]}
            on:select={() => lastSelectedInner = innerRefs[index]} />
    {/each}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search