Angular 4 patchValue 基于 FormArray 中的索引

Angular 4 patchValue based on index in FormArray

我希望在用户在创建的空控件中添加值后更新 formArray

目前,当用户选择添加新项目时,我会使用空值在 formArray 上构建。

buildItem(item?: any, key?: any): FormGroup {
  // Item will pass undefined for initial buildItem in onLoad and new items
  let itemName: string;
  let keyValue: string;
  if (item === undefined) { 
     itemName = ''; key = '' }  
  else { 
     itemName = item.name; keyValue = key 
  };

  /**
   * Builds a single item for form group array in the collectionForm.
   */
   return this.formBuilder.group({ 
                item: [itemName || '', Validators.required], 
                properties: { item, key: key } || {} });
}

这适用于初始创建和更新已添加的项目。问题在于添加了空值的新项目。当我添加一个新项目时,我需要在 properties.key

中添加来自 firebase 的 return 键

在保存新项目的方法中,我添加了 patchValue

this.items.patchValue([{ 
         // item being returned from firebase promise
         item: item.name, 
         properties: { item: item.name, key: item.$key' } 
}]);

然而 patchValue 根本不起作用。当我尝试更新该新值时,尽管这些值已保存到 firebase,但我仍然得到一个 return 值作为空值或在初始 BuildItem() 上设置的保存值而不是更新值patchValue

我在 angular FormArray 文档中看到

It accepts an array that matches the structure of the control, and will do its best to match the values to the correct controls in the group. REF

这是否意味着它可能会也可能不会更新该值.. 它只会尽力尝试?我想如果我可以为我想要修补的值添加索引,那么它根本就不是问题。就像 removeAt(idx)

所以如果我能写出类似

的东西
this.form.patchValue.atIndex(this.idx,[{ 
         item: item.name, 
         properties: { item: item.name, key: item.$key' } 
}];

但我不确定我能做到这一点.. 很确定在那种形式下是不可能的。有什么方法可以专门针对 formArray 中修补的项目,或者我可能没有正确理解这一点。

我可以通过将新值推送到 formArray

来解决这个问题
this.items.push(this.buildItem(...));

但是我必须添加

this.items.removeAt(this.idx); 

为了删除对空构建的初始控制,这看起来不像任何好的代码。

使用FormArray#at + AbstractControl#patchValue:

this.items.at(index).patchValue(...);

DEMO

如果要更新孔数组结构,只需创建一个新的 FormControl 即可:

this.form.setControl('items',  new FormControl(arrayItemsValue));

或者在更新之前删除所有项目:

const items = (<FormArray>this.form.get('items'));
 for (let i = 0; i < items.length; i++) {
     items.removeAt(i);
 }
 this.form.get('items').setValue(arrayItemsValue);

正如 developer033 所说:

Use FormArray#at + AbstractControl#patchValue

但是怎么办?这是一个例子:

中HTML:

<div formArrayName="alternateEmail" *ngFor="let control of alternateEmail.controls; index as i">
  <input type="text" placeholder="Type an alternative email" [formControlName]="i"><input>
</div>

中class:

get alternateEmail(){  return this.registrationForm.get('alternateEmail') as FormArray }

以及实际的补丁方法:

patchDynamicFormBlockValue(){
  this.alternateEmail.at(<index>).patchValue('patchmail@gmail.com')
}

您还可以删除 as FormArray 并在需要时投射:

(<FormArray>this.alternateEmail).at(<index>).patchValue('test@gmail.com')

以TS文件为例

let taskListArrays = this.projectParentForm.get('TaskList') as FormArray;
        
taskListArrays.controls[rowindex].patchValue({"Email":"contacttotanuj@gmail.com"};
let rows = this.manageOrderForm.get('ordersForm') as FormArray;
    rows.controls[this.index].patchValue({totalAmount:totalPrice});
    this.index = this.index + 1;

formarray 设置索引处的值

((this.form.get('controls') as FormArray).at(index) as FormGroup).get('description').patchValue(item.description);