Доброкачественные циклические зависимости - PullRequest
1 голос
/ 07 мая 2020

Пробуя svelte для нового проекта, я написал компонент для редактирования составного объекта, который делегирует редактирование отдельных частей подкомпоненту и воссоздает составной объект всякий раз, когда часть была изменена. Конечно, когда составной объект изменен извне, подкомпоненты должны быть обновлены до новых значений.

В итоге я получил следующее: отредактировано так или иначе, когда редактируется item, выполняется первый реактивный блок, устанавливая переменную обратно в holder.item.

Я не понимаю следующего:

  • Почему выполняется первый реактивный блок? Поскольку item появляется только в левой части присваивания, это не значение, от которого оно зависит.
  • Почему циклическая зависимость «скрыта» от компилятора, почему не следующее работает?
    $: {
        console.log("setting item to "+holder.item);
        item = holder.item;
    }

    $: {
        console.log("setting holder for "+item);
        holder = { item }
    }
  • А почему все работает при переносе обоих реактивных блоков в функции?
    $: setItem(holder)
    function setItem(h) {
        console.log("setting item to "+h.item);
        item = h.item;
    }

    $: setHolder(item);
    function setHolder(i) {
        console.log("setting holder for "+i);
        holder = { item: i }
    }

Полагаться на компилятор кажется странным почему-то не вижу, что делает код, поэтому мне интересно, не придерживаюсь ли я совершенно неправильного подхода.

1 Ответ

2 голосов
/ 07 мая 2020

Реактивный оператор будет повторно выполняться всякий раз, когда изменяется любая из упомянутых переменных. Таким образом, ваш первый оператор будет повторно запущен при изменении holder или item.

Функциональный подход работает, потому что внезапно вы упоминаете только одну переменную (компилятор просматривает только непосредственный блок, а не внутри каких-либо функций, которые будут вызваны)

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

...