Дочерний компонент:
import { Output, EventEmitter } from '@angular/core';
@Output() buttonClicked = new EventEmitter<string>();
onClick() {
this.buttonClicked.emit('Данные события');
}
Родительский компонент:
<app-child (buttonClicked)="handleChildEvent($event)"></app-child>
handleChildEvent(data: string) {
console.log('Событие из дочернего компонента:', data);
}
Родительский компонент:
<app-child #childRef></app-child>
<button (click)="childRef.onClick()">Вызвать метод дочернего</button>
import { ViewChild } from '@angular/core';
import { ChildComponent } from './child.component';
@ViewChild('childRef') childComponent: ChildComponent;
handleClick() {
this.childComponent.onClick();
}
Создаем сервис:
@Injectable({ providedIn: 'root' })
export class EventService {
private childEventSource = new Subject<string>();
childEvent$ = this.childEventSource.asObservable();
emitEvent(data: string) {
this.childEventSource.next(data);
}
}
Дочерний компонент:
constructor(private eventService: EventService) {}
triggerEvent() {
this.eventService.emitEvent('Данные события');
}
Родительский компонент:
constructor(private eventService: EventService) {
this.eventService.childEvent$.subscribe(data => {
console.log('Событие через сервис:', data);
});
}
Полезно, когда нужно одновременно:
Дочерний компонент:
@Input() value: string;
@Output() valueChange = new EventEmitter<string>();
updateValue(newValue: string) {
this.value = newValue;
this.valueChange.emit(newValue);
}
Родительский компонент:
<app-child [(value)]="parentValue"></app-child>
Метод | Когда использовать | Плюсы | Минусы |
---|---|---|---|
Output + EventEmitter | Стандартные события компонента | Чистый Angular подход | Только для прямых потомков |
Сервис с Observable | Компоненты без прямого отношения | Гибкость | Сложнее отладка |
ViewChild | Нужен прямой доступ к методам | Полный контроль | Нарушает инкапсуляцию |
Двусторонняя привязка | Синхронизация значения | Удобный синтаксис | Ограниченный случай |
@Output() userSelected = new EventEmitter<User>();
private destroy$ = new Subject();
ngOnInit() {
this.eventService.childEvent$
.pipe(takeUntil(this.destroy$))
.subscribe(...);
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
<!-- Плохо -->
<app-child (click)="value = value + 1"></app-child>
<!-- Хорошо -->
<app-child (click)="handleClick()"></app-child>
Правильная обработка событий делает компоненты переиспользуемыми и поддерживаемыми.