雙向綁定 (Two-way Binding)
雙向綁定允許子組件不只接收父組件的數據,還可以將數據的更改傳回父組件。
基本原理
雙向綁定本質上是 Property Binding 和 Event Binding 的組合:
父組件透過 Property Binding
[property]
傳遞值給子組件子組件透過 Event Binding
(event)
將更改後的值回傳給父組件
Angular 提供了特定語法 [(property)]
(稱為 "banana in a box") 來簡化這個過程。
傳統實現方式 (裝飾器語法)
雙向綁定遵循強制命名慣例:
@Input 屬性名為任意有效名稱
@Output 屬性名必須是 @Input 名加上 "Change" 後綴
@Input({ required: true }) size!: { width: string; height: string };
@Output() sizeChange = new EventEmitter<{ width: string; height: string }>();
onReset() {
this.sizeChange.emit({
width: '200',
height: '100',
});
}
在父組件中使用:
<app-rect [(size)]="rectSize" />
上面的語法等同於:
<app-rect [size]="rectSize" (sizeChange)="rectSize = $event" />
新版實現方式 (Signal 的 model)
從 Angular 17.2+ 開始,可以使用更簡潔的 model
來實現雙向綁定:
size = model.required<{ width: string; height: string }>();
onReset() {
this.size.set({
width: '200',
height: '100',
});
}
在父組件中的使用方式相同:
<app-rect [(size)]="rectSize" />
model 與傳統方式的比較
model 的優勢
更簡潔的語法 - 不需要單獨定義
@Input
和@Output
類型安全 - 輸入和輸出自動共享相同的類型
一致的 API - 使用與其他 Signal API 一致的
.set()
方法更少的錯誤空間 - 避免命名錯誤和忘記定義 Output
使用方式
使用 model 除了 .set()
方法外,還有其他有用的方法:
// 讀取當前值
const currentSize = this.size();
// 更新部分屬性
this.size.update((current) => ({
...current,
width: '300'
}));
// 監聽變化
effect(() => {
console.log('Size changed:', this.size());
});
Last updated