Reactive Forms: 使用 FormArray

FormArray 的基本概念
當需要處理動態數量的表單控制項時,例如一組複選框、多個輸入欄位或可新增/刪除的表單區塊,FormArray
是一個非常有用的工具。
不同於 FormGroup
使用名稱來組織控制項,FormArray
使用索引來組織,類似於一般的陣列。

基本用法
在 TypeScript 中定義 FormArray
import { FormGroup, FormControl, FormArray } from '@angular/forms';
@Component({...})
export class MyComponent {
myForm = new FormGroup({
name: new FormControl(''),
email: new FormControl(''),
// 使用 FormArray 處理多個複選框
interests: new FormArray([
new FormControl(false), // 第一個複選框,預設未選中
new FormControl(false), // 第二個複選框,預設未選中
new FormControl(false), // 第三個複選框,預設未選中
]),
});
}
在範本中使用 FormArray
<form [formGroup]="myForm">
<div>
<label for="name">Name</label>
<input id="name" formControlName="name">
</div>
<div>
<label for="email">Email</label>
<input id="email" formControlName="email">
</div>
<div formArrayName="interests">
<h3>What are you interested in?</h3>
<div>
<input type="checkbox" id="coding" [formControlName]="0">
<label for="coding">Coding</label>
</div>
<div>
<input type="checkbox" id="music" [formControlName]="1">
<label for="music">Music</label>
</div>
<div>
<input type="checkbox" id="sports" [formControlName]="2">
<label for="sports">Sports</label>
</div>
</div>
<button type="submit">Submit</button>
</form>
注意在範本中,我們:
使用
formArrayName
指定要訪問的 FormArray使用
[formControlName]="index"
綁定 FormArray 中的各個控制項,這裡的 index 是數字索引
訪問 FormArray 的值
可以通過以下方式訪問 FormArray:
// 獲取整個 FormArray
const interestsArray = this.myForm.get('interests') as FormArray;
// 獲取特定控制項
const codingControl = interestsArray.at(0);
// 獲取 FormArray 的所有值
const allInterests = interestsArray.value; // [false, false, false]
// 檢查特定值
console.log(interestsArray.at(0).value); // false
動態操作 FormArray
FormArray 最強大的特性是能夠動態添加和刪除控制項:
// 獲取 FormArray 引用
get interestsArray() {
return this.myForm.get('interests') as FormArray;
}
// 添加新的控制項
addInterest() {
this.interestsArray.push(new FormControl(false));
}
// 移除控制項
removeInterest(index: number) {
this.interestsArray.removeAt(index);
}
// 重置所有控制項
resetInterests() {
this.interestsArray.clear();
// 添加預設控制項
this.interestsArray.push(new FormControl(false));
this.interestsArray.push(new FormControl(false));
}
配合動態範本:
<div formArrayName="interests">
<h3>What are you interested in?</h3>
@for (interest of interestOptions; track $index) {
<div>
<input
type="checkbox"
[id]="'interest-' + $index"
[formControlName]="$index"
>
<label [for]="'interest-' + $index">{{ interest }}</label>
<button type="button" (click)="removeInterest($index)">Remove</button>
</div>
}
<button type="button" (click)="addInterest()">Add Interest</button>
</div>
複雜的 FormArray 用例
FormArray 也可以包含 FormGroup,用於處理更複雜的場景:
// 動態添加地址
addressForm = new FormGroup({
addresses: new FormArray([
new FormGroup({
street: new FormControl(''),
city: new FormControl(''),
postalCode: new FormControl('')
})
])
});
// 添加新地址
addAddress() {
const addresses = this.addressForm.get('addresses') as FormArray;
addresses.push(
new FormGroup({
street: new FormControl(''),
city: new FormControl(''),
postalCode: new FormControl('')
})
);
}
<form [formGroup]="addressForm">
<div formArrayName="addresses">
@for (address of addressForm.get('addresses')['controls']; track $index) {
<div [formGroupName]="$index">
<input formControlName="street" placeholder="Street">
<input formControlName="city" placeholder="City">
<input formControlName="postalCode" placeholder="Postal Code">
<button type="button" (click)="removeAddress($index)">Remove</button>
</div>
}
<button type="button" (click)="addAddress()">Add Address</button>
</div>
</form>
FormArray 的優勢
處理動態數量的控制項:當不確定表單會有多少個控制項時特別有用
批量操作:可以方便地對多個控制項進行批量操作
索引訪問:通過索引可以直接訪問特定控制項
靈活性:可以在執行時添加或刪除控制項
小結
FormArray
是處理動態表單控制項的強大工具,尤其適用於:
多個複選框
動態添加/刪除的表單項
可變數量的相同結構表單區塊
當有一組相似的表單控制項,或需要根據用戶操作動態調整表單結構時,考慮使用 FormArray
。
Last updated