Гид по технологиям

Использование @Output в Angular для передачи событий и данных от дочернего компонента

4 min read Angular Обновлено 05 Dec 2025
Angular @Output — передача событий и данных
Angular @Output — передача событий и данных

Что важно понять

  • @Output — декоратор, который отмечает свойство компонента как источник событий для родителя.
  • EventEmitter — класс для отправки (emit) значений типа T.
  • Это однонаправленный механизм: дочерний компонент «выпускает» событие, родитель «подписывается» в шаблоне.

Когда использовать @Output

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

Быстрый план действий

  1. Создать приложение и компонент-родитель (app) и дочерний компонент (data-component).
  2. В дочернем компоненте объявить @Output() имя = new EventEmitter();
  3. Вызывать this.имя.emit(параметр) при наступлении события.
  4. В шаблоне родителя подписаться:

Два монитора рядом, на каждом открыт редактор с кодом

Подготовка проекта и структура файлов

Предположим, что у вас есть стандартное Angular-приложение. Компонент app — родитель. Для примера создадим дочерний компонент с командой:

ng g c data-component

Файлы, с которыми мы будем работать:

  • src/app/app.component.html
  • src/app/app.component.css
  • src/app/app.component.ts
  • src/app/data-component/data-component.component.html
  • src/app/data-component/data-component.component.css
  • src/app/data-component/data-component.component.ts

Пример 1 — отправка простого события (void)

Шаг 1 — родитель: замените содержимое app.component.html на шаблон с контейнером:

Это родительский компонент

app.component.css:

.parent-component {
  font-family: Arial, Helvetica, sans-serif;
  background-color: lightcoral;
  padding: 20px;
}

Шаг 2 — дочерний компонент: data-component.component.html с кнопкой:

Это дочерний компонент

data-component.component.css:

.child-component {
  font-family: Arial, Helvetica, sans-serif;
  background-color: lightblue;
  margin: 20px;
  padding: 20px;
}

Шаг 3 — подключаем EventEmitter в data-component.component.ts:

import { Component, Output, EventEmitter, OnInit } from '@angular/core';

@Component({
  selector: 'app-data-component',
  templateUrl: './data-component.component.html',
  styleUrls: ['./data-component.component.css']
})
export class DataComponentComponent implements OnInit {
  @Output() buttonWasClicked = new EventEmitter();

  constructor() { }

  ngOnInit(): void { }

  onButtonClick() {
    this.buttonWasClicked.emit();
  }
}

Шаг 4 — слушаем событие в родителе: app.component.html вставляем тег дочернего компонента и подписываемся:


{{message}}

И в app.component.ts добавляем обработчик и сообщение:

message: string = '';

buttonInChildComponentWasClicked() {
  this.message = 'Кнопка в дочернем компоненте была нажата';
}

Теперь при клике в дочернем компоненте родитель получит событие и отобразит сообщение.

Angular приложение с родителем и дочерним компонентом в Firefox

Пример 2 — отправка данных (string[])

Если нужно передать данные при событии, указывайте обобщение EventEmitter.

В data-component.component.ts добавим массив и изменим тип эмиттера:

listOfPeople: string[] = ['Joey', 'John', 'James'];

@Output() buttonWasClicked = new EventEmitter();

onButtonClick() {
  this.buttonWasClicked.emit(this.listOfPeople);
}

В родителе подпишемся и примем данные через $event:


{{message}}

{{data.join(', ')}}

И в app.component.ts:

message: string = '';
data: string[] = [];

buttonInChildComponentWasClicked(dataFromChild: string[]) {
  this.message = 'Кнопка в дочернем компоненте была нажата';
  this.data = dataFromChild;
}

Angular приложение с отображением данных

Полезные советы и распространённые ошибки

  • Синтаксис в шаблоне: используйте (event)=’handler($event)’ — важно, что скобки указывают на событие.
  • Типизация: всегда указывайте тип в EventEmitter, чтобы избежать ошибок компиляции и иметь автодополнение.
  • Не пытаетесь напрямую изменять состояние родителя из дочернего — используйте событие для передачи данных.
  • Не забывайте подписываться в шаблоне, а не в конструкторе через emitter.subscribe, если вам не нужна подписка с отпиской — шаблон автоматически управляет.
  • Если дочерний компонент должен отправлять сложные объекты, передавайте копию (spread или structuredClone), чтобы предотвратить мутацию из родителя.

Important: если дочерний компонент эмитит событие в ngOnInit до того, как родитель успел подписаться, родитель может не получить это событие. Обычно события эмитят в ответ на пользовательские действия.

Когда @Output не подходит (контрпример)

  • Нужна глобальная подписка между несвязанными компонентами — лучше использовать сервис с Subject/BehaviorSubject или менеджер состояния (NgRx, Akita).
  • Требуются двусторонние связи с постоянной синхронизацией сложных объектов — рассмотрите управление состоянием или Input+Output в паре с иммутабельностью.

Альтернативные подходы

  • Использовать сервис с RxJS Subject/Observable для обмена событиями между не связанными компонентами.
  • Использовать Input вместе с двумя-way binding (ngModel) для формы, где требуется синхронизация.
  • Для сложных приложений — централизованные хранилища состояния (NgRx, NGXS).

Контрольный список внедрения (@Output)

  • Объявлен @Output с корректным типом EventEmitter.
  • В дочернем компоненте вызывается emit с нужным значением.
  • В шаблоне родителя подписка на (event)=’handler($event)’.
  • Родитель обрабатывает входные данные и не мутирует исходные объекты дочернего компонента.
  • Компиляция без ошибок типов.

Критерии приёмки

  • При клике в дочернем компоненте родитель получает событие и обновляет интерфейс.
  • Переданные данные в родителе соответствуют ожидаемому типу и содержимому.
  • Нет утечек подписок (если подписки делаются в коде — есть отписка при destroy).

Краткая методология для команды

  1. Договориться об интерфейсе события: имя и тип payload.
  2. Типизировать EventEmitter и параметр обработчика в родителе.
  3. Добавить тесты компонентного поведения (симуляция клика, проверка emitted value).
  4. Документировать контракт события в README модуля.

Пример теста (псевдокод)

// проверить, что при клике вызывается emit с массивом
const comp = fixture.componentInstance;
spyOn(comp.buttonWasClicked, 'emit');
const button = fixture.nativeElement.querySelector('button');
button.click();
expect(comp.buttonWasClicked.emit).toHaveBeenCalledWith(comp.listOfPeople);

Краткий глоссарий (1 строка)

  • @Output — декоратор, помечающий событие, которое компонент может выпустить.
  • EventEmitter — класс для отправки значений типа T родителю.
  • $event — объект или значение, которое передаётся из дочернего компонента при подписке в шаблоне.

Безопасность и производительность

  • Избегайте частого эмита больших структур данных в цикле — лучше передавать идентификатор и загружать данные по требованию.
  • Если данные содержат чувствительную информацию, убедитесь, что родитель имеет право её обрабатывать и отображать.

Резюме

  • @Output и EventEmitter — стандартный способ передачи событий и данных от дочернего компонента к родителю в Angular.
  • Всегда типизируйте EventEmitter и аккуратно обрабатывайте данные, чтобы избегать мутаций.
  • Для нереляционных сценариев рассматривайте сервисы на основе RxJS или менеджеры состояния.

Если нужно, могу добавить проверяемый пример проекта, включающий unit-тесты и e2e-проверки, или предложить шаблон соглашений по именованию событий в вашем кодбэйсе.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как устроить идеальную вечеринку для просмотра ТВ
Развлечения

Как устроить идеальную вечеринку для просмотра ТВ

Как распаковать несколько RAR‑файлов сразу
Инструменты

Как распаковать несколько RAR‑файлов сразу

Приватный просмотр в Linux: как и зачем
Приватность

Приватный просмотр в Linux: как и зачем

Windows 11 не видит iPod — способы исправить
Руководство

Windows 11 не видит iPod — способы исправить

PS5: как настроить игровые пресеты
Консоли

PS5: как настроить игровые пресеты

Как переключить камеру в Omegle на iPhone и Android
Руководство

Как переключить камеру в Omegle на iPhone и Android