Spec-Zone.ru › Angular

Жизненный цикл компонентов

СОВЕТ: Предполагается, что вы уже прочитали руководство по основам. Если вы только начинаете работать с Angular, сначала прочитайте его.

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

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

Жизненный цикл компонента тесно связан с тем, как Angular проверяет изменения в компонентах с течением времени. Чтобы понять этот жизненный цикл, достаточно знать, что Angular обходит дерево приложения сверху вниз, проверяя изменения привязок шаблона. Описанные ниже хуки жизненного цикла выполняются во время этого обхода. При обходе каждый компонент посещается ровно один раз, поэтому всегда следует избегать изменения состояния в середине этого процесса.

Краткое описание

Этап Метод Описание
Создание constructor Стандартный конструктор класса JavaScript . Выполняется при создании экземпляра компонента Angular.
Обнаружение

изменений

ngOnInit Выполняется один раз после инициализации всех входных параметров компонента.
ngOnChanges Выполняется при каждом изменении входных параметров компонента.
ngDoCheck Выполняется при каждой проверке компонента на наличие изменений.
ngAfterContentInit Выполняется один раз после инициализации содержимого компонента.
ngAfterContentChecked Выполняется при каждой проверке содержимого компонента на наличие изменений.
ngAfterViewInit Выполняется один раз после инициализации представления компонента.
ngAfterViewChecked Выполняется при каждой проверке представления компонента на наличие изменений.
Рендеринг afterNextRender Выполняется при следующем отображении в DOM всех компонентов.
afterEveryRender Выполняется при каждом отображении в DOM всех компонентов.
Уничтожение ngOnDestroy Выполняется один раз перед уничтожением компонента.

ngOnInit

Метод ngOnInit выполняется после того, как Angular инициализирует все входные параметры компонентов начальными значениями. ngOnInit компонента выполняется ровно один раз.

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

ngOnChanges

Метод ngOnChanges выполняется после изменения любого входного параметра компонента.

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

Во время инициализации первый вызов ngOnChanges выполняется до ngOnInit.

Просмотр изменений

Метод ngOnChanges принимает один аргумент SimpleChanges. Этот объект представляет собой Record, сопоставляющий имя каждого входного параметра компонента с объектом SimpleChange. Каждый объект SimpleChange содержит предыдущее и текущее значения входного параметра, а также флаг, указывающий, изменился ли входной параметр впервые.

Для более строгой проверки типов можно указать текущий класс или this в качестве первого аргумента обобщённого типа.

@Component({
  /* ... */
})
export class UserProfile {
  name = input('');

  ngOnChanges(changes: SimpleChanges<UserProfile>) {
    if (changes.name) {
      console.log(`Previous: ${changes.name.previousValue}`);
      console.log(`Current: ${changes.name.currentValue}`);
      console.log(`Is first ${changes.name.firstChange}`);
    }
  }
}

Если для каких-либо входных свойств задан alias, запись SimpleChanges всё равно использует в качестве ключа имя свойства TypeScript, а не псевдоним.

ngOnDestroy

Метод ngOnDestroy выполняется один раз непосредственно перед уничтожением компонента. Angular уничтожает компонент, когда он больше не отображается на странице, например, если он скрыт с помощью @if или при переходе на другую страницу.

DestroyRef

Вместо метода ngOnDestroy можно внедрить экземпляр DestroyRef. Чтобы зарегистрировать callback, который будет вызван при уничтожении компонента, вызовите метод onDestroy объекта DestroyRef.

@Component({
  /* ... */
})
export class UserProfile {
  constructor() {
    inject(DestroyRef).onDestroy(() => {
      console.log('UserProfile destruction');
    });
  }
}

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

Также можно использовать DestroyRef, чтобы расположить код настройки рядом с кодом очистки, вместо того чтобы помещать весь код очистки в метод ngOnDestroy.

Определение уничтожения экземпляра

DestroyRef предоставляет свойство destroyed, позволяющее проверить, был ли уже уничтожен данный экземпляр. Это полезно, чтобы не выполнять операции с уничтоженными компонентами, особенно при работе с отложенной или асинхронной логикой.

Проверяя destroyRef.destroyed, можно предотвратить выполнение кода после очистки экземпляра и избежать потенциальных ошибок, таких как NG0911: View has already been destroyed..

ngDoCheck

Метод ngDoCheck выполняется перед каждой проверкой Angular шаблона компонента на наличие изменений.

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

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

Во время инициализации первый вызов ngDoCheck выполняется после ngOnInit.

ngAfterContentInit

Метод ngAfterContentInit выполняется один раз после инициализации всех дочерних элементов, вложенных в компонент (его содержимого).

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

ngAfterContentChecked

Метод ngAfterContentChecked выполняется при каждой проверке изменений во вложенных в компонент дочерних элементах (его содержимом).

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

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

ngAfterViewInit

Метод ngAfterViewInit выполняется один раз после инициализации всех дочерних элементов в шаблоне компонента (его представлении).

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

ngAfterViewChecked

Метод ngAfterViewChecked выполняется при каждой проверке изменений дочерних элементов в шаблоне компонента (его представлении).

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

Здесь можно получить доступ к обновлённому состоянию запросов представления, однако попытка изменить состояние в этом методе приводит к ошибке ExpressionChangedAfterItHasBeenCheckedError.

afterEveryRender и afterNextRender

Функции afterEveryRender и afterNextRender позволяют зарегистрировать callback рендеринга, который будет вызван после того, как Angular завершит отображение в DOM всех компонентов страницы.

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

Функции afterEveryRender и afterNextRender необходимо вызывать в контексте внедрения зависимостей, обычно в конструкторе компонента.

Callback рендеринга можно использовать для выполнения операций с DOM вручную. Рекомендации по работе с DOM в Angular см. в разделе Использование API DOM.

Callback рендеринга не выполняются при рендеринге на стороне сервера или предварительном рендеринге во время сборки.

Этапы after*Render

При использовании afterEveryRender или afterNextRender работу можно разделить на этапы. Этап позволяет управлять последовательностью операций с DOM, задавая порядок, в котором операции записи выполняются до операций чтения, чтобы свести к минимуму перерасчёт макета. Чтобы передавать данные между этапами, функция этапа может возвращать результат, доступный на следующем этапе.

import {Component, ElementRef, afterNextRender} from '@angular/core';

@Component({
  /*...*/
})
export class UserProfile {
  private prevPadding = 0;
  private elementHeight = 0;

  constructor() {
    const elementRef = inject(ElementRef);
    const nativeElement = elementRef.nativeElement;

    afterNextRender({
      // Use the `Write` phase to write to a geometric property.
      write: () => {
        const padding = computePadding();
        const changed = padding !== this.prevPadding;
        if (changed) {
          nativeElement.style.padding = padding;
        }
        return changed; // Communicate whether anything changed to the read phase.
      },

      // Use the `Read` phase to read geometric properties after all writes have occurred.
      read: (didWrite) => {
        if (didWrite) {
          this.elementHeight = nativeElement.getBoundingClientRect().height;
        }
      },
    });
  }
}

Этапы выполняются в следующем порядке; всего их четыре:

Этап Описание
earlyRead Используйте этот этап для чтения свойств и стилей DOM, влияющих на макет, только если они необходимы для последующих вычислений. По возможности пропускайте этот этап, отдавая предпочтение этапам write и read.
write Используйте этот этап для записи свойств и стилей DOM, влияющих на макет.
mixedReadWrite Этап по умолчанию. Используйте его для операций, которым необходимо и читать, и записывать свойства и стили, влияющие на макет. По возможности избегайте этого этапа, отдавая предпочтение явным этапам write и read.
read Используйте этот этап для чтения любых свойств DOM, влияющих на макет.

Интерфейсы жизненного цикла

Для каждого метода жизненного цикла Angular предоставляет интерфейс TypeScript. При желании можно импортировать эти интерфейсы и implement их, чтобы убедиться в отсутствии опечаток и ошибок в написании.

Название каждого интерфейса совпадает с названием соответствующего метода без префикса ng. Например, интерфейс для ngOnInit — это OnInit.

@Component({
  /* ... */
})
export class UserProfile implements OnInit {
  ngOnInit() {
    /* ... */
  }
}

Порядок выполнения

На следующих диаграммах показан порядок выполнения хуков жизненного цикла Angular.

Во время инициализации

Рендеринг

Обнаружение изменений

ngOnChanges

ngOnInit

ngDoCheck

ngAfterContentInit

ngAfterViewInit

ngAfterContentChecked

ngAfterViewChecked

constructor

afterNextRender

afterEveryRender

Последующие обновления

Рендеринг

Обнаружение изменений

ngOnChanges

ngDoCheck

ngAfterContentChecked

ngAfterViewChecked

afterEveryRender

Порядок выполнения директив

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

Super-powered by Google ©2010–2025.
Code licensed under an MIT-style License. Documentation licensed under CC BY 4.0.
https://angular.dev/guide/components/lifecycle

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API