在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 而出錯
較不建議採用此方式