Хуки жизненного цикла Angular на практике
Angular — один из самых популярных интерфейсных фреймворков для создания надежных веб-приложений на основе компонентов. Компонент в приложении Angular имеет жизненный цикл, который проходит через разные фазы, начиная с его создания. Перехватчики жизненного цикла позволяют вам подключаться к этим различным фазам по мере создания, обновления и уничтожения компонентов, чтобы получить больший контроль над вашим приложением.
В этой статье я расскажу об хуках жизненного цикла Angular и покажу, когда и как их использовать.
Что такое крючки жизненного цикла?
Крючки жизненного цикла — это синхронизированные методы, которые активируются обнаружением изменений Angular. Поскольку Angular постоянно выполняет обнаружение изменений в данных, условия текущего цикла обнаружения изменений определяют, как используются хуки жизненного цикла. Наиболее важным моментом в хуках жизненного цикла является последовательность, в которой они используются. Порядок выполнения не меняется, и они выполняются на основе предопределенной последовательности событий загрузки, сгенерированных циклом обнаружения.
Хук, конечно, работает только тогда, когда он удовлетворяет определенным критериям, определенным текущим циклом обнаружения изменений. Некоторые ресурсы доступны только при запуске определенного хука. Вы можете использовать перехватчики жизненного цикла, чтобы подключиться к важным этапам жизненного цикла компонента или директивы, чтобы инициировать новые экземпляры, инициализировать обнаружение изменений, когда это необходимо, реагировать на изменения во время обнаружения изменений и очищать перед уничтожением экземпляра.
Мы можем сгруппировать эти хуки в следующие две категории:
- Хуки, связанные с самим компонентом или директивами:
- "конструктор()"
- ngOnChanges
- ngOnInit
- нгдочек
- ngOnDestroy
- Хуки, связанные с дочерними компонентами:
- ngAfterContentInit
- ngAfterContentChecked
- ngAfterViewInit
- ngAfterViewChecked
Теперь давайте рассмотрим их один за другим.
конструктор()
Жизненный цикл компонента начинается с создания компонента. Метод Constructor() — это первый хук, который вызывается, когда Angular вызывает new для класса для создания компонента или директивы, и он обеспечивает правильную инициализацию полей и подклассов класса. .
В настоящее время мы не можем получить доступ к входным свойствам компонента. Ни один из его подкомпонентов не создается. Кроме того, проецируемый контент также недоступен. После создания экземпляра компонента Angular запускает первый цикл обнаружения изменений компонента.
нгончанжес
ngOnChanges — это хук жизненного цикла, который вызывается один раз при создании экземпляра компонента и всякий раз, когда одно или несколько входных свойств с привязкой к данным изменяются до ngOnInit() (если компонент содержит входные данные, привязанные к @Input). Он запускается, когда Angular изменяет свойства ввода с привязкой к данным или сбрасывает их. Объект SimpleChanges с текущим и предыдущим значениями свойств передается методу в качестве необязательного параметра.
нгонинит
Хук ngOnInit вызывается после первого вызова ngOnChanges(). Даже когда ngOnChanges() не вызывается при отсутствии входных данных, привязанных к шаблону, ngOnInit() все равно вызывается. Он запускается после завершения инициализации связанных с данными или входных свойств компонента.
После завершения отрисовки дочернего компонента вызывается ngOnInit(). Затем, даже после обновления источника данных свойства с привязкой к входу в родительском компоненте, ngOnInit() не вызывается. Итак, мы можем назвать ngOnInit() одноразовой ловушкой. Он заботится исключительно об инициализации.
нгдочекк
При каждом запуске обнаружения изменений ngDoCheck() вызывается сразу после ngOnChanges(), а при первом запуске он вызывается сразу после ngOnInit(). сильный>. Он обнаруживает и реагирует на изменения, которые сам Angular не может или не будет обнаруживать. После выполнения детектора изменений по умолчанию ngDoCheck() обычно выполняет обнаружение изменений.
Разработчики могут явно проверять свои данные, используя ngDoCheck() в качестве пользовательского детектора изменений, комбинируя его с ChangeDetectorRef. Однако стоит отметить, что при неправильном обращении это может привести к проблемам с производительностью.
нгафтерконтентинит
После первого ngDoCheck выполняется хук ngAfterContentInit(). Он срабатывает, когда компонент или содержимое директивы инициализированы.
нгафтерконтентечекед
ngAfterContentChecked вызывается после ngAfterContentInit() и каждого последующего ngDoCheck(). Этот хук вызывается после того, как Angular оценил содержимое, спроецированное в директиве или компоненте.
нгафтервиевинит
Хук ngAfterViewInit выполняется после ngAfterContentChecked(). Представление всегда загружается сразу после содержимого. Таким образом, он запускается после того, как Angular инициализирует представления и дочерние представления компонента или представление, содержащее директиву.
В этом хуке у нас есть доступ к ElementRef элемента ViewChildren после создания компонента. ngAfterViewInit ожидает разрешения запросов @ViewChild или @ViewChildren. Тот же самый вид компонента помогает нам запрашивать эти элементы. Мы можем использовать этот хук для случаев, когда загрузка содержимого представления зависит от других компонентов представления.
нгафтервиевчеккед
Хук ngAfterViewChecked вызывается после ngAfterViewInit() и каждого последующего ngAfterContentChecked(). Он запускается после того, как Angular проверил представления компонента и дочерних элементов или представление, содержащее директиву. Следите за установкой любых переменных здесь, которые привязаны к шаблону. Это приведет к неожиданным ошибкам.
нгондестрой
Когда жизненный цикл компонента заканчивается, Angular отвечает за его уничтожение. Однако, прежде чем компонент или директиву можно будет уничтожить, необходимо выполнить несколько важных шагов по отсоединению. ngOnDestroy() — это хук жизненного цикла, отвечающий за выполнение этих шагов.
Теперь давайте посмотрим, как реализовать хуки жизненного цикла Angular на простом примере.
Здесь мы собираемся реализовать простой компонент с именем UserDetails. Кроме того, компонент UserDetails будет иметь дочерний компонент с именем Random для случайного создания идентификаторов пользователей с предоставленным пользователем префиксом. Вы можете отображать или скрывать эту форму UserDetails в основном представлении.
См. код компонента UserDetails ниже.
import { Component, Injectable, OnInit, OnChanges, DoCheck, AfterViewChecked, AfterViewInit, AfterContentInit, AfterContentChecked, OnDestroy } from "@angular/core"; @Component({ selector: "userdetails", template: ` <div> <h2>Name :</h2> <input type="text" [(ngModel)]="name" /> <input type="text" [(ngModel)]="prefix" /> <random [user]="prefix" (generateUserId)="onGenerateUserId($event)" ></random> <h3>UserID : {{ userid }}</h3> </div> ` }) export class UserDetails implements OnInit, OnChanges, DoCheck, AfterViewChecked, AfterViewInit, AfterContentInit, AfterContentChecked, OnDestroy { name: string = "Angular"; prefix: string = ""; userid: string = ""; constructor() { this.name = ""; console.log("Parent constructor() called"); } onGenerateUserId(uid:string) { console.log("Generating UserID"); this.userid = uid; } ngOnInit() { this.name = "John Doe"; console.log("Parent ngOnInit() called"); } ngOnChanges() { console.log("Parent ngOnChanges() called"); } ngDoCheck() { console.log("Parent ngDoCheck() called"); } ngAfterViewChecked() { console.log("Parent ngAfterViewChecked() called"); } ngAfterViewInit() { console.log("Parent ngAfterViewInit() called"); } ngAfterContentInit() { console.log("Parent ngAfterContentInit() called"); } ngAfterContentChecked() { console.log("Parent ngAfterContentChecked() called"); } ngOnDestroy() { console.log("Parent ngOnDestroy() called"); } }
См. код компонента генератора случайных идентификаторов ниже.
import {Component, Injectable, Input, Output, EventEmitter, OnInit, OnChanges, DoCheck, AfterViewChecked, AfterViewInit, AfterContentInit, AfterContentChecked, OnDestroy} from '@angular/core' @Component({ selector: 'random', template: ` <div> <input type='button' (click)='random()' value='Generate UserID' /> </div> ` }) export class Random implements OnInit, OnChanges, DoCheck, AfterViewChecked, AfterViewInit, AfterContentInit, AfterContentChecked, OnDestroy{ @Input() user:string; @Output() generateUserId: EventEmitter<string> = new EventEmitter<string>(); constructor(){ this.user = ''; console.log('Child constructor() called'); } random(){ var t = new Date().getTime(); this.generateUserId.emit(this.user + t.toString()); console.log('random() called'); } ngOnInit(){ console.log('Child ngOnInit() called'); } ngOnChanges(){ console.log('Child ngOnChanges() called'); } ngDoCheck(){ console.log('Child ngDoCheck() called'); } ngAfterViewChecked(){ console.log('Child ngAfterViewChecked() called'); } ngAfterViewInit(){ console.log('Child ngAfterViewInit() called'); } ngAfterContentInit(){ console.log('Child ngAfterContentInit() called'); } ngAfterContentChecked(){ console.log('Child ngAfterContentChecked() called'); } ngOnDestroy(){ console.log('Child ngOnDestroy() called'); } }
После нажатия кнопки Показать сведения о пользователе конструкторы родительского и дочернего компонентов запускаются первыми, поскольку происходит инициализация родительского компонента.
Код основного компонента приложения выглядит следующим образом.
//app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: [ './app.component.css' ] }) export class AppComponent { name:string; showUserDetails: boolean; btnText: string; constructor() { this.showUserDetails = false; this.btnText = 'Show'; } toggleUserDetails(){ this.showUserDetails = !this.showUserDetails; this.btnText = this.showUserDetails ? 'Hide' : 'Show'; } } //app.component.html <h2>Angular Lifecycle Events Example</h2> <div> <input type='button' (click)='toggleUserDetails()' value='{{btnText}} User Details'> </div> <div *ngIf='showUserDetails'> <userdetails></userdetails> </div>
ngAfterContentInit и ngAfterContentChecked вызываются сразу после ngOnInit() и ngDoCheck(). Это означает, что сначала будет отображаться весь внешний HTML. Затем дочерний компонент начинает инициализацию. Как объяснялось ранее, при инициализации или обновлении любых дочерних свойств, связанных с Input(), будет вызываться ngOnChanges().
Присмотревшись, мы видим, что перехватчики ngAfterViewInit и ngAfterViewChecked дочернего компонента появляются в начале последовательности выполнения. Это указывает на то, что представление дочернего компонента будет сначала визуализировано, прежде чем передать его родительскому. Затем родительский компонент полагается на предположение, что его собственное представление завершено, так как его дочерние представления завершены. Следовательно, далее срабатывают хуки ngAfterViewInit и ngAfterViewChecked родительского компонента.
На следующем рисунке показан процесс вывода при нажатии кнопки Показать сведения о пользователе.
После того как вы введете букву в текстовое поле в качестве префикса идентификатора пользователя и затем нажмете кнопку Создать идентификатор пользователя, вы получите вывод консоли, как показано на следующем рисунке.
Таким образом, полный поток будет выглядеть следующим образом.
Родительский компонент будет уничтожен, когда вы нажмете кнопку Скрыть сведения о пользователе, в зависимости от *ngIf. Поскольку родитель уничтожен, каждый из его потомков также будет удален. Это означает, что родительские компоненты будут очищены после очистки дочерних компонентов. Результат показан ниже.
Ресурсы
Подробнее см. в демо-приложении в репозитории GitHub Angular Lifecycle Hooks.
Заключение
В этой статье я обсудил хуки жизненного цикла Angular, а также когда, где и почему они используются при разработке приложений Angular. По мере расширения наших проектов хуки жизненного цикла позволяют нам точно контролировать поведение наших компонентов с момента их создания. Таким образом, жизненно важно понять концепцию и практиковать ее, чтобы воспользоваться ее преимуществами.
Спасибо за чтение!
Библиотека Angular UI component от Syncfusion — единственный набор, который вам когда-либо понадобится для создания приложения. Он содержит более 80 высокопроизводительных, легких, модульных и адаптивных компонентов пользовательского интерфейса в одном пакете.
Для существующих клиентов новейшая версия Essential Studio доступна для загрузки на странице Лицензии и загрузки. Если вы не являетесь клиентом Syncfusion, вы можете попробовать нашу 30-дневную бесплатную пробную версию, чтобы ознакомиться с доступными функциями. Также ознакомьтесь с нашими демонстрациями на GitHub.
Если у вас есть вопросы, свяжитесь с нами через наши форумы поддержки, портал поддержки или портал обратной связи. Мы всегда рады Вам помочь!
Связанные блоги
- Что нового в 2022 году, том 4: Essential JS 2
- Полное руководство по созданию интеллект-карты с использованием компонента Angular Diagram
- Простая отладка приложений Angular с помощью Angular DevTools
- Освоение строго типизированных реактивных форм в Angular: пошаговое руководство
Первоначально опубликовано на https://www.syncfusion.com 31 января 2023 г.