Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

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

Компонент создаётся, когда его тег появляется на странице, и удаляется, когда тег исчезает — например, когда условие @if стало ложным. На ключевых шагах Angular вызывает методы-хуки с определёнными именами. В них размещают код, который должен выполниться в нужный момент.

Основные хуки

ХукКогда вызывается
constructorОбъект создан, входы ещё не заданы
ngOnChangesИзменилось значение входа (и перед ngOnInit)
ngOnInitОдин раз, после первой установки входов
ngAfterViewInitОдин раз, когда шаблон компонента выведен
ngOnDestroyПеред удалением компонента

Чаще всего нужны два: ngOnInit для начальной загрузки и ngOnDestroy для уборки.

ngOnInit

Загрузим сохранённые задачи из localStorage, когда список появляется на странице:

// src/app/todo-list/todo-list.ts
import { Component, OnInit, signal } from '@angular/core';
import { Todo } from '../todo';
 
@Component({
  selector: 'app-todo-list',
  templateUrl: './todo-list.html',
})
export class TodoList implements OnInit {
  todos = signal<Todo[]>([]);
 
  ngOnInit() {
    const saved = localStorage.getItem('todos');
    if (saved) {
      this.todos.set(JSON.parse(saved));
    }
  }
}

Интерфейс OnInit не обязателен, но с ним TypeScript проверит, что имя метода написано правильно. Добавьте задачу, обновите страницу — задача на месте, если в уроке о сигналах вы добавили effect для сохранения.

ngOnDestroy

Таймеры и подписки сами не останавливаются при удалении компонента. Сделаем часы, которые показывают текущее время:

ng generate component clock
// src/app/clock/clock.ts
import { Component, OnDestroy, OnInit, signal } from '@angular/core';
 
@Component({
  selector: 'app-clock',
  template: `<p>Сейчас {{ time() }}</p>`,
})
export class Clock implements OnInit, OnDestroy {
  time = signal(new Date().toLocaleTimeString());
  private timerId = 0;
 
  ngOnInit() {
    this.timerId = window.setInterval(() => {
      this.time.set(new Date().toLocaleTimeString());
    }, 1000);
  }
 
  ngOnDestroy() {
    clearInterval(this.timerId);
  }
}

Вставьте <app-clock /> в шаблон списка дел и добавьте Clock в imports — время обновляется каждую секунду. Когда компонент исчезнет, ngOnDestroy остановит таймер.

DestroyRef

Уборку можно описать сразу рядом с кодом, который её требует, через inject(DestroyRef):

// src/app/clock/clock.ts
import { Component, DestroyRef, inject, signal } from '@angular/core';
 
@Component({
  selector: 'app-clock',
  template: `<p>Сейчас {{ time() }}</p>`,
})
export class Clock {
  time = signal(new Date().toLocaleTimeString());
 
  constructor() {
    const id = setInterval(() => {
      this.time.set(new Date().toLocaleTimeString());
    }, 1000);
    inject(DestroyRef).onDestroy(() => clearInterval(id));
  }
}

Результат тот же, но запуск и остановка таймера стоят рядом. Функция inject() подробно разобрана в уроке о сервисах.

Частая ошибка

Читать входное свойство в конструкторе. В этот момент родитель ещё ничего не передал, а обязательный вход input.required() и вовсе выбросит ошибку. Код, которому нужны входы, пишите в ngOnInit или в computed.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.