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

Использование @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
Автор
Редакция

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

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство