В этой статье мы узнаем, зачем нам нужен хук жизненного цикла ngDoCheck и служба KeyValueDiffers, воссоздав директиву ngStyle с нуля.

Сервис KeyValueDiffers:

Служба KeyValueDiffers отличается тем, что отслеживает изменения, вносимые в объект с течением времени, а также предоставляет API для реагирования на эти изменения. (мы увидим позже, как мы можем использовать эту услугу)

Жизненный цикл ngDoCheck:

Все мы знакомы с крючком жизненного цикла ngOnChanges. Вы можете реализовать ngOnChanges, чтобы получать уведомления об изменениях, если ваш Input является примитивным типом или ваши Input ссылочные изменения (с использованием некоторой стратегии неизменности).

Если ссылка на модель не меняется, но изменяется какое-то свойство модели Input, вы можете реализовать ловушку жизненного цикла ngDoCheck, чтобы создать логику обнаружения изменений вручную.

Хорошо, хватит разговоров, давайте приступим к кодированию.

Мы создаем директиву ngStyle и реализуем интерфейс DoCheck. Мы также внедряем наши службы KeyValueDiffers, Renderer и ссылку на элемент хоста (ElementRef).

Мы создаем ngStyle Input как установщик. Если у нас нет разницы, мы создаем новую разницу, вызывая:

this._differ = this._differs.find(value).create(null);

Метод find() просто ищет отличное от нашего значения.

Если вам интересно, вот как Angular проверяет, есть ли у нее правильная разница для нашего значения:

return obj instanceof Map || isJsObject(obj);

Метод create() просто создает различие и возвращает экземпляр DefaultKeyValueDiffer. (ноль для ChangeDetectorRef)

Нам нужно реализовать ловушку жизненного цикла ngDoCheck, потому что, как мы уже говорили, мы не меняем ссылку на наш объект, поэтому мы не можем использовать ngOnChanges.

Например:

<div [ngStyle]=”style”></div>
// In our component constructor
this.style = { color: 'red' };
// After click event
this.style.color = 'blue'

Затем мы проверяем, изменился ли наш объект, вызывая метод diff() с новым значением. Если никаких изменений нет, возвращаемое значение будет нулевым. Если есть какие-либо изменения, возвращаемое значение будет объектом, который предоставляет три метода, которые мы можем использовать для реакции на эти изменения.

Эти методы говорят сами за себя, мы можем передать обратный вызов каждому изменению, которое нам нужно знать. Каждый обратный вызов дает вам запись типа KeyValueChangeRecord. Это объект с тремя полезными ключами: key, currentValue и previousValue..

Теперь каждый раз, когда у нас есть изменение, мы вызываем метод _setStyle(), который вызывает setElementStyle() из нашей службы рендеринга, чтобы установить новый стиль элемента.

Подробнее об услуге Renderer читайте здесь.

Правда в том, что это исходный код Angular для ngStyle. Я не писал этот код и не верю ему; Я просто объясняю концепции и то, как это работает под капотом.

Вы можете увидеть полный исходный код здесь.

😱 🚀 Вы когда-нибудь пробовали акиту?

Одна из ведущих библиотек государственного управления, Akita использовалась в бесчисленных производственных средах. Он постоянно развивается и совершенствуется.

Будь то объекты, поступающие с сервера, или данные о состоянии пользовательского интерфейса, у Akita есть специализированные хранилища, мощные инструменты и индивидуальные плагины, которые помогают управлять данными и устраняют необходимость в огромных объемах шаблонного кода. Мы / я очень рекомендую вам попробовать.



Подпишитесь на меня в Medium или Twitter, чтобы узнать больше об Angular, Akita и JS!