Игривый подход к изучению новых хуков жизненного цикла Angular, предназначенных только для браузера.
Поскольку команда Angular продолжает работать над улучшениями инфраструктуры, такими как детальная реактивность с сигналами и частичная гидратация с помощью рендеринга на стороне сервера (SSR), они представили два новых хука. Эти хуки будут особенно полезны, когда нам нужно обновить DOM с нашим состоянием, но только при запуске в браузере.
Иногда необходимо использовать API-интерфейсы только для браузера, чтобы вручную читать или писать DOM. Это может быть сложно сделать с описанными выше событиями жизненного цикла, поскольку они также будут выполняться во время рендеринга на стороне сервера и предварительного рендеринга. Для этой цели в Angular предусмотрены
afterRender
иafterNextRender
. Эти функции можно использовать безоговорочно, но они будут влиять только на браузер. Обе функции принимают обратный вызов, который будет запущен после завершения следующего цикла обнаружения изменений (включая любые вложенные циклы).
Итак, это означает, что теперь у нас есть два метода, которые только выполняются в браузере, что делает наши обновления DOM безопасными даже при использовании SSR или предварительной отрисовки.
afterNextRender
Выполните однократную инициализацию или наблюдайте за одним конкретным изменением в DOM.
Это событие запускается один раз после следующего цикла обнаружения изменений, инициируемого Angular. Таким образом, это событие идеально подходит для любого кода инициализации, который вам нужен в вашем приложении, например, для любых сторонних библиотек или API-интерфейсов только для браузера (например, для инициализации API ResizeObserver).
послеRender
Синхронизируйте состояние с DOM.
При каждом цикле обнаружения изменений это событие будет инициироваться и выполняться. Это идеально подходит для обновления DOM каждый раз, когда Angular обнаруживает изменения. Вы можете использовать его для дополнительной записи (или чтения) DOM на основе обновления приложения.
Догони синюю точку!
Хорошо, мы все знаем, что читать документацию о новой функции — это не то же самое, что использовать ее в приложении. Вы будете следить за мной, пока я буду демонстрировать небольшое приложение (или лучше сказать игру?), которое я создал с помощью Сигналы и afterNextRender и afterRender.
Вы можете попробовать игру здесь: https://after-render.netlify.app/ и просмотреть код на GitHub https://github.com/eduardoRoth/after-render
Цель этой игры — перемещать красную точку по доске, пока не коснетесь синей точки, которая (сюрприз!) переместится в другое положение.
Мы используем HostListener
для отслеживания события keydown
на странице, а затем перемещаем красную точку. Если обновленные координаты красной точки совпадают с координатами синей точки, мы также обновляем ее положение.
@HostListener('document:keydown', ['$event']) onKeydown( event: KeyboardEvent, ) { switch (event.key) { case 'ArrowLeft': // left this.moveHorizontal(-PIXELS_MOVEMENT); break; case 'ArrowUp': // up this.moveVertical(-PIXELS_MOVEMENT); break; case 'ArrowRight': // right this.moveHorizontal(PIXELS_MOVEMENT); break; case 'ArrowDown': // down this.moveVertical(PIXELS_MOVEMENT); break; } }
Мы используем WritableSignal<number>
для хранения оценки и обновления DOM каждый раз, когда ее значение обновляется. Положение красной и синей точек также сохраняется в файле WritableSignal<[number, number]>
, который представляет координаты x и y доски.
position = signal<[number, number]>([0, 0]); positionPointToTouch = signal<[number, number]>([ CONTAINER_SIZE - POINT_SIZE, CONTAINER_SIZE - POINT_SIZE, ]); score = signal<number>(0);
У нас есть два метода обновления точек и один — проверить, коснулась ли красная точка синей точки:
private movePoint(axis: number, amount: number, maxAxisPosition: number) {...} private movePointToTouch() {...} private hasTouchedPoint() {...}
movePoint
обрабатывает обновление сигнала положения красной точки новыми координатами.
movePointToTouch
обрабатывает обновление сигнала положения синей точки новыми координатами.
hasTouchedPoint
— это метод проверки совпадения координат положения красной и синей точки, а затем вызывает метод для перемещения синей точки.
Итак, логика у нас настроена, но как мы можем обновить DOM? Используя afterRender
!
По мере обновления сигналов они запускают цикл обнаружения изменений в Angular, который затем запускает событие afterRender
. Мы можем извлечь из этого пользу, вызывая методы, которые рисуют красную и синюю точку на доске каждый раз, когда обрабатывается изменение:
constructor() { afterRender(() => { this.drawPoint(); this.drawPointToTouch(); }); ... } private drawPoint() { const [x, y] = this.position(); this.point.nativeElement.setAttribute( 'style', `transform: translateY(${y}px) translateX(${x}px)`, ); } private drawPointToTouch() { const [x, y] = this.positionPointToTouch(); this.pointToTouch.nativeElement.setAttribute( 'style', `transform: translateY(${y}px) translateX(${x}px)`, ); }
Мы используем afterNextRender
для запуска метода init board, который просто обновляет DOM. Это идеальное место, если мы хотим однажды изменить наш DOM.
constructor() { ... afterNextRender(() => { this.drawInitBoard(); }); } private drawInitBoard() { this.playingArea.nativeElement.setAttribute( 'style', `border:3px solid #dedede;`, ); const instructions = document.createElement('div'); instructions.innerHTML = `<p style="font-weight: bolder; font-size:1.2rem;">Using your arrow keys, move the red dot to catch the blue one</p>`; this.playingArea.nativeElement.parentNode.append(instructions); }
Как вы можете видеть, оценка обновляется с помощью функции обнаружения угловых изменений посредством детальной реактивности сигналов, но положение точек обрабатывается событием afterRender
.
ExpressionChangedAfterItHasBeenCheckedError что?
Если вы попытаетесь обновить любую переменную в событии afterRender
, вы получите эту ошибку; поэтому это событие следует использовать только для дополнительных операций чтения и записи в DOM, а не для обновления вашего состояния или чего-либо еще.
Обновления DOM стали проще
Итак, используя afterRender
, мы гарантируем, что красные и синие точки обновляются в DOM каждый раз, когда обновляется их значение позиции.
Наши приложения открывают множество возможностей, которые откроют afterRender
и afterNextRender
.
Помните, что
afterRender
иafterNextRender
находятся на стадии предварительного просмотра и их API могут быть изменены.
О HeroDevs
HeroDevs — студия разработки программного обеспечения и консалтинга, специализирующаяся на интерфейсной разработке. Наша команда является автором или соавтором таких проектов, как Angular CLI, Angular Universal, Scully, XLTS — расширенная долгосрочная поддержка AngularJS, Vue2, Protractor и многих других. Мы работаем с быстрорастущими стартапами и некоторыми крупнейшими компаниями мира, такими как Google, GE, Capital One, Experian, T-Mobile, Corteva и другими. Узнайте больше о нас на сайте herodevs.com.