@Input và @Output là cách tiêu chuẩn để một component cha và con giao tiếp: @Input truyền dữ liệu (cha → con), còn gửi các sự kiện (con → cha). Điều này phản ánh pattern phổ quát "props xuống, events lên".
@Input và @Output là cách tiêu chuẩn để một component cha và con giao tiếp: @Input truyền dữ liệu (cha → con), còn gửi các sự kiện (con → cha). Điều này phản ánh pattern phổ quát "props xuống, events lên".
@Output// con: UserCardComponent
import { Component, Input } from "@angular/core";
@Component({ selector: "app-user-card", template: `<h2>{{ user.name }}</h2>` })
export class UserCardComponent {
@Input() user!: User; // nhận dữ liệu từ cha
@Input() showEmail = false; // với giá trị mặc định
}
<!-- cha truyền dữ liệu qua property binding -->
<app-user-card [user]="currentUser" [showEmail]="true"></app-user-card>
// con phát ra một sự kiện mà cha có thể lắng nghe
import { Component, Output, EventEmitter } from "@angular/core";
@Component({
selector: "app-user-card",
template: `<button (click)="onDelete()">Delete</button>`,
})
export class UserCardComponent {
@Output() deleted = new EventEmitter<number>(); // khai báo một sự kiện output
onDelete() {
this.deleted.emit(this.user.id); // phát ra kèm payload
}
}
<!-- cha lắng nghe qua event binding -->
<app-user-card [user]="u" (deleted)="removeUser($event)"></app-user-card>
Con phát ra thông qua một EventEmitter; cha bind tới nó bằng (eventName) và nhận payload qua $event. Con không bao giờ sửa đổi dữ liệu của cha một cách trực tiếp — nó yêu cầu hành động bằng cách phát sự kiện.
Cha ──[user]──────────────→ Con (@Input: dữ liệu xuống)
Cha ←──(deleted)=removeUser─ Con (@Output: sự kiện lên)
name = input<string>(); // @Input dựa trên signal (Angular mới hơn)
deleted = output<number>(); // @Output dựa trên signal
Angular gần đây bổ sung các hàm input()/output() dựa trên signal như một lựa chọn thay thế.
@Input/@Output là cốt lõi của giao tiếp cha-con và các component tái sử dụng trong Angular — chúng thực thi luồng dữ liệu một chiều (xuống qua input, lên qua sự kiện) giúp giữ dữ liệu dễ đoán và các component decoupled.
Hiểu cặp này là thiết yếu để kết hợp bất kỳ UI Angular không tầm thường nào; còn để giao tiếp giữa các component không liên quan, bạn sẽ dùng một service dùng chung hoặc một thư viện state.