@Inputと@Outputは、親コンポーネントと子コンポーネントが通信するための標準的な方法です:**@Inputはデータを下へ渡し(親→子)、@Output**はイベントをへ送ります(子→親)。これは普遍的な「props下、events上」パターンを反映しています。
// child: UserCardComponent
import { Component, Input } from "@angular/core";
@Component({ selector: "app-user-card", template: `<h2>{{ user.name }}</h2>` })
export class UserCardComponent {
@Input() user!: User; // receives data from the parent
@Input() showEmail = false; // with a default
}
<!-- parent passes data via property binding -->
<app-user-card [user]="currentUser" [showEmail]="true"></app-user-card>
// child emits an event the parent can listen to
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>(); // declares an output event
onDelete() {
this.deleted.emit(this.user.id); // emit with a payload
}
}
<!-- parent listens via event binding -->
<app-user-card [user]="u" (deleted)="removeUser($event)"></app-user-card>
子コンポーネントはEventEmitter経由でエミットし、親コンポーネントは(eventName)でそれにバインドして、ペイロードを$eventとして受け取ります。子コンポーネントは親のデータを直接変更することはありません — イベントをエミットすることでアクションを要求します。
Parent ──[user]──────────────→ Child (@Input: data down)
Parent ←──(deleted)=removeUser─ Child (@Output: events up)
name = input<string>(); // signal-based @Input (newer Angular)
deleted = output<number>(); // signal-based @Output
最近のAngularでは、シグナルベースのinput()/output()関数が代替手段として追加されています。
@Input/@OutputはAngularの親子通信と再利用可能なコンポーネントの中核です — 単方向データフロー(入力経由で下へ、イベント経由で上へ)を強制することで、データが予測可能になり、コンポーネントが疎結合になります。
このペアを理解することは、任意の非自明なAngular UIを構成するために不可欠です。無関係なコンポーネント間の通信には、代わりに共有サービスまたは状態管理ライブラリを使用します。