Что касается Ember, я чувствую, что каждый день узнаю что-то новое. Для меня самые большие «ага» моменты возникают во время рефакторинга. Видеть что-то, что «не кажется» правильным, и пытаться выяснить почему, а затем как это исправить. Один из примеров, который постоянно возникает у нас, - это вычисляемые свойства.

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

Все мы знакомы с тем, как выглядит вычисленное свойство, вот надуманный пример:

name: computed('person.name', function() {
  return get(person, 'name');
});

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

set(this, 'name', 'will');

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



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

Когда вы определяете вычисляемое свойство, у вас также есть возможность добавить к нему внутренние функции get () и set (). Это даст нам гораздо более точный контроль над кэшированием значений cp. Вы бы написали это так:

name: computed('person.name', {
  get() {
    get(this, 'person.name');
  },
  set(_, value) {
    return value;
  })
});

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

Есть два способа изменить кешированное значение.

Первый - сделать недействительным свойство кеша, изменив наблюдаемый ключ (person.first). При следующем доступе к свойству будет запущена внутренняя функция get (), и новое значение в «person.first» будет возвращено и кэшировано.

Второй - set () кешированное значение. Если бы мы сделали следующее:

set(this, 'name', 'Will');

Будет вызвана внутренняя функция set (), у нее есть два аргумента: ключ и значение. Мы можем игнорировать ключ, и все, что нам нужно сделать, это вернуть значение (в данном случае это будет «Will»). Это заменит кешированное значение, и когда вы получите доступ к вычисляемому свойству, будет возвращено значение «Will».

Слово предупреждения здесь: если вы установите один из зависимых ключей в функции set (), это не приведет к аннулированию кеша. Вы также должны всегда возвращать что-то в функции установки, отсутствие возврата будет означать, что «undefined» будет кэшироваться как значение этого свойства.

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

Если вы зададите для свойства другое значение, оно будет кэшировано и заменит значение «Will». Если бы вы сделали кеш недействительным, изменив наблюдаемый ключ, функция get () будет запущена, и значение свойства будет пересчитано на основе «person.name», и это значение будет кэшировано.

Взгляните на этот твидл тлеющего угля в качестве примера:



В этом примере у нас также есть кнопка для сброса формы, которая делает недействительным кеш для вычисляемого свойства, что приводит к повторному запуску функции get и возврату начального значения для кеширования.

Это новое понимание вычисляемых свойств действительно упростило способ изменения состояния в наших компонентах и ​​сделало возврат к начальному состоянию компонентов тривиальным. Этот тип функциональности особенно полезен в формах, где вы не хотите, чтобы свойства теней присутствовали в вашем компоненте, и вы хотите легко сбросить состояние, если пользователь отменит.