在Reactive Form使用陣列資料ーFormArray
前言
Reactive Form(嚮應式表單)可以很方便的處理表單裡的大小事務
若資料集是單純的陣列資料,則須配合FormArray使用
使用方式
FormBuilder.group()初始值
在form裡預設值直接傳前[]
就好
constructor(private readonly fb: FormBuilder) { }
this.form = this.fb.group({
//...省略其他欄位...
items: [[]],
})
直接console.log印出來會是
{
items: []
}
無法直接patchValue傳值
一般由api取得內容後,要填入Reactive Form(嚮應式表單),可以直接用patchValue()
填值
但formArray不行
須透過formBuilder.array
封裝後,再使用setControl()
填入
const items = MY_DATA_FROM_API.items; // ['a', 'b', 'c']
this.form.patchValue(MY_DATA_FROM_API); // 填入其他欄位內容
this.form.setControl('items', this.fb.array(items)); // 陣列元素須另外填入
異動formArray資料內容
增加元素:push
就如同陣列習慣,要增加元素就直接push
不能直接將元素單純push進去,須透過formBuilder.control(元素)
封裝後再push
下例使用一般的input,綁定[(ngModal)]="itemValue"
為例
addItem(): void {
if (this.itemValue && !this.form.get('items').value.includes(this.itemValue)) {
(this.form.get('items') as FormArray).push(this.fb.control(this.inputValue));
}
this.itemValue = ''; // 加入成功後,清除輸入框內容
}
刪除元素:removeAt(i)
在html裡的*ngFor
指定i
,直接傳入
removeItem(i: number) {
(this.form.get('items') as FormArray).removeAt(i);
}
清除formArray
要透過removeAt逐一清除
clearItems() {
while (this.form.get('items').value.length !== 0) {
this.removeItem(0);
}
}
或是暴力作法,直接重新放一個新的
clearItems() {
this.form.setControl('items', this.fb.array([]));
}
缺點就是若有formArray.valueChanges
的訂閱,會因遺失 reference 而出錯
較不建議採用此方式