У меня есть родительский шаблон (App.svelte), который создает массив доступных для записи и передает его компоненту (RedOrBlueOrPurple.svelte
). Компонент перебирает элементы. Я хочу передать массив доступных для записи (вместо создания единственной доступной для записи, которая содержит весь массив объектов), потому что я хочу добавить обработчики subscribe
для каждого элемента индивидуально, когда вещи изменяются внутри элемента. В противном случае мой обработчик подписки должен был бы выяснить, какой элемент был изменен, что выглядит как дополнительная работа.
В этом коде ниже первая кнопка действительно меняет фиолетовый атрибут, потому что за этим вызовом update
следует refresh
, который сбрасывает родительские значения. Я хотел бы избежать этого вызова, если это возможно, и просто использовать доступный для записи в качестве интерфейса, который понимают и могут использовать родитель и ребенок.
Кроме того, мне не нравится, что шаблон должен использовать map
на каждом, чтобы вытащить предмет, получите значение магазина (используя внутренний вызов svelte get_store_value
), но я не знаю, как бы я использовал {#each items as $items...}
в противном случае (я не могу понять, как использовать $item
Вот). Есть ли более элегантный способ получения значения?
Кроме того, и это кажется очень прискорбным, тот факт, что консоль не отображает ошибки, когда я вызываю refre sh и задаю переменную const
, выглядит так он нарушает правила JS и все еще компилируется. Я знаю, что Svelte комментирует этот призыв под капотом, чтобы отреагировать на изменение, но это кажется неправильным.
Это на этом REPL здесь: https://svelte.dev/repl/84fbae4358494844a79a7f119b084f01?version=3.19.2
<script>
import { writable } from 'svelte/store';
import RedOrBlueOrPurple from './RedOrBlueOrPurple.svelte';
const items = [];
items.push( writable( { blue: true }));
items.push( writable( { blue: false, red: true }));
items.push( writable( { blue: true, red: true }));
const refresh = () => {
items = items;
};
</script>
<RedOrBlueOrPurple {refresh} {items}/>
<script>
import { get_store_value } from 'svelte/internal';
export let items;
export let refresh;
const purple = (item, callRefresh) => {
item.update( i => {
i.purple = true;
return i;
});
// We only call this for the first button, and if we don't,
// the items aren't updated, even though we do call update on
// the store correctly.
if (callRefresh) {
refresh();
}
};
</script>
{#each items.map( item => ({ item, value: get_store_value(item) })) as { item, value}, index }
<h1>
Item : { index }
</h1>
<div>
RED: { value.red ? "Red" : "Not red"}
</div>
<div>
BLUE: { value.blue ? "Blue" : "Not blue"}
</div>
<div>
PURPLE: { value.purple ? "Purple" : "Not purple"}
</div>
<button on:click={ () => { purple(item, index === 0) } }>Change to purple</button>
{/each}