首页 > 解决方案 > 我们如何使用带有可自定义控件的 ngFor formArrays?

问题描述

问题摘要:我们的应用程序要求用户可以“添加产品”,从而生成新字段。html:

   <div formArrayName="products">
     <label>Products *:</label>
     <div *ngFor="let product of products.controls; index as i;">
       <div [formGroupName]="i">
         <div class="form-group row">
<!--...-->

.ts:

  createProduct(): FormGroup {
    return this.formBuilder.group({
      product: [null, Validators.required], // selector (product)
      contractMonth: [null, Validators.required], // selector (months)
      contractYear: [null, Validators.required], // selector (years)
      comment: [null] // text
    });
  }

但是,由于最近推出了新的产品类型,不同的产品类型具有不同的字段类型。

首先,用户从 productList 选择器中选择一个产品。根据选择的产品类型,我们仅显示相关字段。例如,对于蔬菜,我们可能会要求选择 vegey-ness,而对于水果,我们可能会要求选择fruity-ness。

这种动态formGroup控件我们怎么做呢?如果没有大量的 ngIfs 和冗余控件,是否有可能?我们之前也遇到过验证器和 ngIf 的问题。

我们不确定最终的 html 是否应该如下所示:

<ng-container *ngIf='Type1'>
<!--Type 1 controls->
<!--...-->
<ng-container *ngIf='Type2'>
<!--...-->

或 createProduct() 函数更改:

  createProduct(): FormGroup {
    return this.formBuilder.group({
      if (productName === 'Type1'){
       product: [null, Validators.required], // selector (product)
       contractMonth: [null, Validators.required], // selector (months)
       contractYear: [null, Validators.required], // selector (years)
       comment: [null] // text
      }
      // or switch statement and onwards
    },{
// ...
    });
  }

以前,我们(绿色开发人员)在 2 种产品类型可用时进行硬编码。但现在这种情况很快就会失控。我们希望我们的编码更干净,而不是像意大利面那样。我们目前将冗余字段作为空值发送。(而不仅仅是没有这些字段)。

如果这个问题没有很好地说明,我深表歉意。我会按需编辑!

使用大量 *ngIfs。但是我的同事已经被淹没和困惑了。他在验证者方面也有麻烦。setValidators、Validators.required 和 updateValueAndValidity() 等等。

<!--Example of contract selector, of which there can be many, depending on how many times the user clicks the add product button-->
<ng-select [virtualScroll]="true" [items]="productList" bindLabel="productName" [searchFn]="customSearch" formControlName="product">
                  <ng-template ng-option-tmp let-item="item">
                    {{ item.productName }} <br />
                    <small>Exchange: {{ item.exchange }}</small> <br />
                    <small>Contract Code: {{ item.contractCode }} 
                     </small>
                  </ng-template>
                </ng-select>
<!--...-->

感谢您的阅读!

标签: htmlangulartypescriptbootstrap-modalngfor

解决方案


我找到了我要找的东西! 如何使用 *ngIf 其他? 和 NgSwitch 等(关于如何在 NgFor 中嵌套 NgSwitch 也有各种答案!)

谢谢!如果有任何事情发生,我会更新我的页面。


推荐阅读