Nano Hash - криптовалюты, майнинг, программирование

Можно ли связать одну и ту же переменную между несколькими компонентами с помощью Svelte?

Если один и тот же компонент используется несколько раз из одного и того же контекста, возможно ли совместное использование связанного свойства между их экземплярами?

Например, если у меня есть компонент, который создает флажки, как можно объединить выбор (bind:group) для селектора букв и селектора чисел?

В этом примере, если выбрано несколько букв, выделение правильно распространяется и связывается. Однако, если затем выбраны числа, выбранные буквы заменяются выбранными числами, вместо того, чтобы присоединять выбранные числа к выбранным буквам.

// App.svelte
<script>
    import Selector from './Selector.svelte';

    let selection = [];

    $: console.log(selection);
</script>

<h2>Letters</h2>
<Selector options={['A', 'B', 'C']} bind:selection />

<h2>Numbers</h2>
<Selector options={[1, 2, 3]} bind:selection />

// Selector.svelte
<script>
    export let options;
    export let selection;
</script>


<div class="selector">
    {#each options as option}
    <label>
        <input type="checkbox" value={option} bind:group={selection} />
                {option}
    </label>
    {/each}
</div>

REPL: https://svelte.dev/repl/f97f859ea567473b97832f8933d / а>


Ответы:


1

Да и нет.

Фактически, то, что вы сделали, связывает переменную между различными экземплярами компонента. Объект тот же === с той же ссылкой ... Пока это не произойдет:

        selection = value;

Это из скомпилированного кода вашего REPL. Когда вы устанавливаете флажок, Svelte создает новый массив, содержащий отмеченные значения, и присваивает его переменной bind:group. На данный момент переменная все та же ... Но ее содержимое было заменено новой ссылкой на массив. Поэтому при смене группы вы теряете ценность предыдущей.

Вы можете доказать это себе, обновив свой REPL, сделав selection объектом вместо массива, и добавив некоторую логику для хранения значения по ключу.

Например, в App.svelte измените выделение на объект:

    let selection = {};

А в Selector.svelte привяжите к промежуточной переменной и напишите только свойства объекта (а не сам объект):

<script>
    export let options;
    export let selection;

    let group = []
    $: for (const option of options) {
        selection[option] = group.includes(option)
    }
</script>


<div class="selector">
    {#each options as option}
    <label>
        <input type="checkbox" value={option} bind:group />
                {option}
    </label>
    {/each}
</div>

Обновленный REPL

Каким-то образом распечатайте значение selection, и вы увидите, что оно не сбрасывается и содержит значение из всех селекторов.

Итак, возвращаясь к вашей проблеме, проблема на самом деле заключается в назначении. И напрямую с этим ничего не поделаешь. В Svelte нет ничего для объединения связанных значений ... Однако теперь, когда мы поняли проблему, мы можем ее обойти.

Решение состоит в том, чтобы не связывать напрямую общедоступную опору (т.е. selection), а вместо этого привязываться к промежуточной переменной, как в нашем предыдущем примере, и каким-то образом самостоятельно выполнять слияние (здесь доступно множество способов).

Вот один из способов переписать компонент Selector, чтобы разрешить совместное использование переменных:

<script>
  export let options;
  export let selection;

    let group = []

    const update = () => {
      selection = selection
        .filter(x => !options.includes(x))
        .concat(group)
    }

    // when group changes, update
    $: group, update()
</script>

<div class="selector">
  {#each options as option}
    <label>
      <input type="checkbox" value={option} bind:group />
          {option}
    </label>
  {/each}
</div>

REPL

Примечание: я не помещал выражение selection = selection.filter(x => !options.includes(x)).concat(group) непосредственно в реактивный блок, потому что наше обновление будет запускаться при изменении selection. А поскольку он общий, он изменится снаружи. Фактически, это было бы условием бесконечного цикла, но у Svelte есть защита специально от этого (для реактивных блоков). Но лучше не полагаться на это, а также не тратить зря. Здесь он сработает только при изменении нашего локального group, а это как раз то, что нам нужно.

01.04.2020
  • Спасибо! Отличный ответ. Намного чище, чем то, что я делал. 01.04.2020
  • Примечание: непроверенные значения удаляются из selection. 01.04.2020
  • Ой, извините, что вы правы. Я не думал об этом. Я обновил пример, добавив кое-что, что должно работать лучше. 01.04.2020
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..