简体   繁体   English

基于 FormArray 索引的 Angular 4 patchValue

[英]Angular 4 patchValue based on index in FormArray

I am looking to update a formArray after the user adds a value in an empty created control.我希望在用户在创建的空控件中添加值后更新formArray

Currently when the user selects to add a new item i build onto the formArray with empty values.目前,当用户选择添加一个新项目时,我将使用空值构建到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 } || {} });
}

This works fine for the initial creation and the update of items that are already added.这适用于初始创建和已添加项目的更新。 The issue is with new items that are added with empty values.问题在于添加了空值的新项目。 When i add a new item i need to add the return key from firebase in the properties.key当我添加一个新项目时,我需要在properties.key添加来自 firebase 的返回键

In the method for the save of that new item i added a patchValue在保存该新项目的方法中,我添加了一个patchValue

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

However the patchValue is not working at all.但是patchValue根本不起作用。 When i try the update that new value, although the values have been saved to firebase i still get a return for the values as empty or the save values set on the initial BuildItem() and not the updated values in the patchValue当我尝试更新该新值时,尽管这些值已保存到 firebase,但我仍然将这些值返回为空或在初始BuildItem()上设置的保存值而不是patchValue的更新值

I see on the angular FormArray Documentation that我在 angular FormArray Documentation 上看到

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 参考文献

Does that mean that it might and might not update that value .. it will just do its best to try?这是否意味着它可能会也可能不会更新该值……它只会尽力尝试? I figure if i can add the index for the value that i want to patch then it should not be a issue at all.我想如果我可以为我想要修补的值添加索引,那么它根本不应该是一个问题。 like with the removeAt(idx)就像removeAt(idx)

So if i can write something like所以如果我能写出类似的东西

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

But not sure i can do that .. well pretty sure that it not possible in that form.但不确定我能做到这一点……很确定它不可能以这种形式出现。 Is there any way to specifically target the item that gets patched in a formArray or am i maybe not understanding this correctly.有什么方法可以专门针对在formArray打补丁的项目,或者我可能没有正确理解这一点。

I can sort of get away with this by pushing the new value onto the formArray我可以通过将新值推送到formArray这个formArray

this.items.push(this.buildItem(...));

however then i have to add但是我必须补充

this.items.removeAt(this.idx); 

In order to remove the initial control on the empty build , which does not seem like any sort of good code.为了删除空构建的初始控制,这似乎不是任何一种好的代码。

Use FormArray#at +AbstractControl#patchValue :使用FormArray#at +AbstractControl#patchValue

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

DEMO演示

You can do this simply by creating a new FormControl if you want to update the hole array structure:如果要更新孔阵列结构,只需创建一个新的 FormControl 即可完成此操作:

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

Or by removing all items before updating them :或者在更新之前删除所有项目:

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

As developer033 said:正如 developer033 所说:

Use FormArray#at + AbstractControl#patchValue使用 FormArray#at + AbstractControl#patchValue

But how to?但是怎么办? Here's an example:下面是一个例子:

In the HTML:在 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>

In the class:在课堂里:

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

And the actual patch method:和实际的补丁方法:

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

You can also remove the as FormArray and cast just when you need:您还可以删除as FormArray并在需要时进行转换:

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

In TS file use below as an example在 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 set value at index formarray 在索引处设置值

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM