Angular 4 patchValue基于FormArray中的索引

21 angular angular-reactive-forms

我想formArray在用户在空创建的控件中添加值后更新a .

目前,当用户选择将我构建的新项目添加到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 } || {} });
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

然而,patchValue根本不起作用.当我尝试更新新值时,虽然值已保存到firebase,但仍然会返回值为空的值或者在初始值上设置的保存值BuildItem()而不是更新的值patchValue

我在有角度的FormArray文档中看到了

它接受一个与控件结构匹配的数组,并尽最大努力将值与组中的正确控件相匹配.REF

这是否意味着它可能会也可能不会更新该值..它会尽力尝试吗?我想如果我可以添加我想修补的值的索引,那么它根本不应该是一个问题.喜欢的removeAt(idx)

所以,如果我能写出类似的东西

this.form.patchValue.atIndex(this.idx,[{ 
         item: item.name, 
         properties: { item: item.name, key: item.$key' } 
}];
Run Code Online (Sandbox Code Playgroud)

但不确定我能做到这一点......非常确定这种形式是不可能的.有没有办法专门针对那些被修补的项目,formArray或者我可能没有正确理解这一点.

我可以通过将新值推到上面来侥幸逃脱 formArray

this.items.push(this.buildItem(...));
Run Code Online (Sandbox Code Playgroud)

然而,我必须补充

this.items.removeAt(this.idx); 
Run Code Online (Sandbox Code Playgroud)

为了删除空构建的初始控制,这似乎不是任何好的代码.

dev*_*033 24

使用FormArray#at+ AbstractControl#patchValue:

this.items.at(index).patchValue(...);
Run Code Online (Sandbox Code Playgroud)

  • 一个完整的例子可以使这个答案完整. (11认同)

aba*_*het 8

如果要更新孔阵列结构,只需创建一个新的 FormControl 即可完成此操作:

this.form.setControl('items',  new FormControl(arrayItemsValue));
Run Code Online (Sandbox Code Playgroud)

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

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


小智 5

正如 developer033 所说:

使用 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>
Run Code Online (Sandbox Code Playgroud)

在课堂里:

get alternateEmail(){  return this.registrationForm.get('alternateEmail') as FormArray }
Run Code Online (Sandbox Code Playgroud)

和实际的补丁方法:

patchDynamicFormBlockValue(){
  this.alternateEmail.at(<index>).patchValue('patchmail@gmail.com')
}
Run Code Online (Sandbox Code Playgroud)

您还可以as FormArray在需要时删除和强制转换:

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