问题
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