What is the best way to signal 50+ nested components to execute a child component function in svelte 3

天涯浪子 提交于 2021-01-29 03:08:18

问题


Example In a table with rows (child components). I need To do a text search in every row and mark the rows with results.

I'am starting with svelte and it looks very very interesting. How to signal all svelte child components (rows) to execute the row search.

I can toggle a store, but there must be a fundemental better way?

Child.svelte:

<script>
    export let child;   // child id
    import {signal} from './store.js';
    let fired = false

    $: if ($signal) {
        fired = true;
        setTimeout(() => fired = false, 500);
    }
</script>

{#if fired} 
  <p>Child-{child}: fired</p>
{/if}

UPDATE This is a lot better:
Child.svelte:

<script>
    import { onDestroy } from 'svelte';
    import {search} from './store.js';
    export let child;   
    let result = '';

    // observe the search term
    const unsubscribe = search.subscribe(value => {
      result = `Child-${child} searched : ${value}`;
    });
    onDestroy(unsubscribe);
</script>

{#if $search} 
  <p>{result}</p>
{/if

App.svelte:

<script>
  import {search} from './store.js';
  import Child from './Child.svelte';
</script>

<!-- <input bind:value={$search}> -->
<input on:change={e => {search.set(e.target.value)}}>

<div>
  <h3>{$search}</h3>
  <Child child={'A'} />
  <Child child={'B'} />
</div>

回答1:


But is can be done without the need of a store. Pass search as a prop. Make the search function call reactive in the nested component. Now Svelte will take care of search changes.

Search.svelte:

<script>
  import Row from './Row.svelte';
  let data = {
    'A': 'Dit is een stuk tekst uit een veel grotere tekst', 
    'B': 'En hier nog een stuk tekst'
   };

   let search = '';
   function searchHandler(e) {
     search = e.target.value;  
   }
</script>

<style>
  table, th {
    border-collapse: collapse;
    border: 1px solid black;
  } 
</style>

<h3>Search column <input on:blur={searchHandler}></h3>

<table>
  <tr>
    <th>Row</th>
    <th>Found</th>
    <th>Text</th>
  </tr>      
  <Row rowId={'A'} text={data.A} {search}/>
  <Row rowId={'B'} text={data.B} {search}/>
</table>

Row.svelte:

<script>
  export let rowId; 
  export let text;
  export let search = '';

  let result = text;
  let found = false;

  function searchNow(s) {
    let re = new RegExp(s, 'gi');
    result = text.replace(re, `<mark>${s}</mark>`);
    found = s !== '' && text !== result;
  }

  $: searchNow(search)    // make it reactive

</script>

<style>
  td {
    border: 1px solid black;
  }
</style>

<tr>
  <td>{rowId}</td>
  <td>{found}</td>
  <td>{@html result}</td>
</tr>

Instead of $: searchNow(search) you can use a labeled block statement:

  $: {    // make it reactive block
    console.log('searchNow', search);
    searchNow(search)
  }


来源:https://stackoverflow.com/questions/57994637/what-is-the-best-way-to-signal-50-nested-components-to-execute-a-child-componen

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!