В Svelte вы можете использовать `array = array`, чтобы пометить массив как требующий refre sh в представлении? - PullRequest
0 голосов
/ 05 февраля 2020

То есть, используя

array = array;

, чтобы запустить представление для обновления sh с текущим array?

Например, в следующих случаях используется

cards = [...cards, {name}];

для "добавления" записи в массив cards, но путем присвоения cards новому массиву и cards в представлении будет обновлено.

sample on: https://svelte.dev/repl/3ed20e7bac2e4b65944c98485d9217b3?version=3.18.1
(просто введите несколько имен, и список ниже обновится).

Однако при вводе n имен это O (n²), потому что каждый раз при создании нового массива O (n). Если (1) пользователь должен вводить несколько или дюжину имен за раз, это не такая большая проблема, или (2) пользователь может вводить имя от нескольких секунд до 20 секунд, тогда любая задержка пользовательского интерфейса в течение 0,2 секунд не является большой проблемой, когда запись до 1000 или 2000 имен. (пользователю, вероятно, будет лучше добавить сервер и базу данных на случай отключения электроэнергии в любом случае.)

Но в случае, если нам не нужно время O (n²), мы также можем использовать:

    cards.push({name});
    cards = cards;

это вызовет refre sh в представлении. Так Svelte не делает "грязную проверку"? Правда ли, что по сравнению с Angular, Vue и React они выполняют грязную проверку, фактически преобразовывая массив в строку и проверяя, изменился ли массив?

sample: https://svelte.dev/repl/70cc3b08f6864ef387c691b8f126a7fd?version=3.18.1

Без строки cards = cards; список не будет обновляться в представлении:

образец: https://svelte.dev/repl/25f41c51798d425e805fb4586a843363?version=3.18.1

То есть Svelte не выполняет грязную проверку, а использует cards = something; как подсказку, что cards изменился, даже на cards = cards? Так можем ли мы просто использовать это как общий метод, чтобы пометить что-то как грязное, если мы используем array.push(), чтобы программа могла работать быстрее? Мог ли Svelte предположить, что cards изменился, обнаружив, что есть оператор cards.push()?

Обновление: было обнаружено, что при добавлении ключа к каждому элементу списка cards = cards не требуется и мне интересно, почему:

https://svelte.dev/repl/d78158ae54684bf28b8c2e9b527f1915?version=3.18.1

<ul>
  {#each cards as card, i (i)}
    <li>{card.name}</li>
  {/each}
</ul>

Ответы [ 2 ]

4 голосов
/ 05 февраля 2020

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

Обнаружение таких вещей, как array.push(...), не является действительно практично - гораздо лучше иметь единый, понятный способ сообщить компилятору «это изменилось», и оператор присваивания таков.

Причина, по которой он работает с ключом каждого блока, но не с ключом одна из них на самом деле из-за ошибки - я поднял вопрос: https://github.com/sveltejs/svelte/issues/4373

2 голосов
/ 05 февраля 2020

Вы можете использовать пользовательские хранилища для эмуляции «обнаружения изменений, вызванных push() методом».

См. Этот ответ от Rich Harris https://svelte.dev/repl/2699eb0fe7dd4621b3e585aec1a30d01?version=3.17.3

...