【问题标题】:Angular FormArray With Dynamically Added Controls具有动态添加控件的 Angular FormArray
【发布时间】:2020-06-25 03:52:32
【问题描述】:

不久前我开始在 Angular 9 上进行编码,并且正在创建一个反应式表单,它具有通过 FormArray Abstract 动态添加的表单控件,但是每当我尝试遍历 formArray 控件的 value 属性时,我得到这个令人难以置信的奇怪错误我已经尝试了将近 12 个小时。当我在值节点下只有一个数组条目时,不会出现此错误。有人能指出做错了什么吗?

这是错误:

这是我的表单生成器:

this.quotationForm = this.fb.group({
      customerId : new FormControl('', Validators.required),
      customerName : new FormControl(),

      'contact' : this.fb.group({
        customerAddress : new FormControl('',Validators.required),
        customerPhone : new FormControl('', Validators.required),
        customerEmail : new FormControl('', Validators.email),
      }),

      'itemsgroup' : new FormArray(
        [
          this.fb.group({
            item : '',
            quantity : '',
            amount : ''
          })
        ],{validators : Validators.required}),

      currency : new FormControl(),
      discount : new FormControl(),
      taxRate : new FormControl(),
      taxAmount : new FormControl(),
      purchase : new FormControl(),
      note : new FormControl(),
      total :new FormControl(),
      ref : new FormControl(),
      tailor : this.usrId,
      datecreated : new FormControl(this.model, Validators.required),
});

这是来自我的组件的函数调用:

 getSelectedItemsSum(){
    let quotesTotal = 0;
    let itemsgroupAmt = 0;
    let itemsgroupQty = 0;
    let itemsgroup = this.itemsgroup();

    if(itemsgroup.touched == true && itemsgroup.status !== 'INVALID'){
      if(itemsgroup.value.length > 1){
        console.log(itemsgroup.value);
        for(let i = 0; i <= itemsgroup.value.length; i++){

          if((itemsgroup.value[i].amount != '' || itemsgroup.value[i].amount != 0) && (itemsgroup.value[i].quantity != '' || itemsgroup.value[i].quantity != '')){
            itemsgroupAmt += itemsgroup.value[i].amount;
            itemsgroupQty += itemsgroup.value[i].quantity;
          }
        }

        quotesTotal = (itemsgroupAmt * itemsgroupQty);
      }else{
        if((itemsgroup.value[0].amount != '' || itemsgroup.value[0].amount != 0) && (itemsgroup.value[0].quantity != '' || itemsgroup.value[0].quantity != 0))
          quotesTotal = (parseInt(itemsgroup.value[0].amount) * parseInt(itemsgroup.value[0].quantity));
      }
    }else return;

    console.log(itemsgroup)
  }

这是itemsgroup() function

itemsgroup() : FormArray{
    return this.quotationForm.get('itemsgroup') as FormArray;
  }

我的html模板的代码sn-p:

<div formArrayName="itemsgroup" class="row row-xs mb-2">
                <div *ngFor="let group of itemsgroup().controls; let i = index" class="col-xl-12">
                  <div [formGroupName]="i" class="row row-xs mb-2 relative">
                    <div class="col-md-4">
                      <input type="text" formControlName="item" placeholder="Item {{i + 1}}" class="form-control" required>
                    </div>
                    <div class="col-md-4">
                      <input 
                        type="number" 
                        formControlName="quantity" 
                        placeholder="Quantity {{ i + 1 }}" 
                        min="1" step="1" value="1"
                        class="form-control" required>
                    </div>
                    <div class="col-md-4">
                      <input 
                        (change)="getSelectedItemsSum()"
                        type="number" 
                        formControlName="amount" 
                        placeholder="Amount {{ i + 1 }}"  
                        class="form-control" required>
                    </div>
                    <button 
                      (click)="removeItemGroup(i)"
                      *ngIf="(i >= 1)"
                      mat-fab 
                      mat-stroked-button 
                      color="primary" 
                      matTooltip="Delete Item Group" 
                      style="position:absolute;right:7px;top:17px;width:22px;height:22px;">
                      <i style="position:absolute;top:5px;left:8px">*</i>
                    </button>
                  </div>
                </div>
              </div>

这是我的表格(截断):

【问题讨论】:

  • itemgroup 的结果是什么?
  • 你能写(复制粘贴)代码而不是拍照吗?它使阅读和测试自己变得更容易。干杯
  • 我已经做到了

标签: javascript angular multidimensional-array angular-reactive-forms angular-abstract-control


【解决方案1】:

请更改 let i = 1 而不是 let i = 0,因为您在 for 循环中使用小于等于 i&lt;=itemgroup.value.length

改变你的循环条件,如下所示,

for (let i = 1; i <= itemgroup.value.length; i++)
{    

// your code

}

for (let i = 0; i < itemgroup.value.length; i++)
{    

  // your code

}

【讨论】:

  • 我认为这正是我正在做的事情
  • 我想我现在了解你了。我将进行编辑并重试
  • 这个建议for(let i = 0; i &lt; itemsgroup.value.length; i++) 解决了我的问题。谢谢!
【解决方案2】:
  1. 请更改方法名称itemsgroup(),您的方法和formArray同名。
  2. 在模板中将&lt;div *ngFor="let group of itemsgroup().controls; let i = index" class="col-xl-12"&gt;改为

    <div *ngFor="let group of quotationForm.get('itemsgroup').controls; let i = index" class="col-xl-12">
    

不相关的建议

而不是在模板中的控件上使用change 事件。你应该使用'FormControl'提供的valueChanges observable,这样你会更“Angular way”。

【讨论】:

  • 当您还是新手时,很难知道“Angular Way”。感谢您的建议,
  • 标识符“控件”未定义。 “AbstractControl”不包含这样的成员
  • 请将您的代码发布到您正在构建表单的位置quotationForm
  • 只是我的笔记本电脑还是 valueChanges() 触发了两次,onBlur 和 onChange?
  • 我将编辑我的问题并添加 formBuilder 的代码
猜你喜欢
  • 1970-01-01
  • 2019-03-10
  • 2019-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-26
  • 2018-05-20
  • 1970-01-01
相关资源
最近更新 更多