【问题标题】:Angular 4 patchValue based on index in FormArray基于FormArray中的索引的Angular 4 patchValue
【发布时间】:2017-10-11 13:50:27
【问题描述】:

我希望在用户在创建的空控件中添加值后更新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 的返回键

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

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

但是patchValue 根本不起作用。当我尝试更新该新值时,尽管这些值已保存到 Firebase,但我仍然会返回空值或初始 BuildItem() 上设置的保存值,而不是 patchValue 中的更新值

我在 angular FormArray 文档中看到

它接受一个与控件结构匹配的数组,并且将尽最大努力将值与组中的正确控件匹配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); 

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

【问题讨论】:

  • this.items.at(index).patchValue(...) 不起作用?
  • @developer033 是的,谢谢,您可以将其添加为答案。
  • 可能有误会,但是为什么要先创建一个空控件,如果要为其设置值呢? :)
  • @AJT_82 如果数据库中的集合为空(它可以允许只有集合名称的空列表),那么我想在页面加载时初始化用户可以添加的默认空输入他们的第一个值与
  • 集合的命名和添加集合项位于不同的视图中,并且具有某种子父关系。因为FormGroup 中的每个输入都是我试图创建的组件尽可能通用,以便我可以在站点范围内使用它

标签: angular angular-reactive-forms


【解决方案1】:

使用FormArray#at + AbstractControl#patchValue:

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

DEMO

【讨论】:

  • 一个完整的例子可以使这个答案变得完整。
【解决方案2】:

如果要更新孔数组结构,只需创建一个新的 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);

【讨论】:

    【解决方案3】:

    正如 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>
    

    在课堂上:

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

    以及实际的patch方法:

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

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

    (&lt;FormArray&gt;this.alternateEmail).at(&lt;index&gt;).patchValue('test@gmail.com')

    【讨论】:

      【解决方案4】:
      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);
      

      【讨论】:

        【解决方案5】:

        在TS文件中使用下面的例子

        let taskListArrays = this.projectParentForm.get('TaskList') as FormArray;
                
        taskListArrays.controls[rowindex].patchValue({"Email":"contacttotanuj@gmail.com"};
        

        【讨论】:

          猜你喜欢
          • 2019-12-19
          • 2017-05-18
          • 2018-12-20
          • 2020-08-29
          • 2020-04-26
          • 2020-04-20
          • 1970-01-01
          • 1970-01-01
          • 2021-07-04
          相关资源
          最近更新 更多