【问题标题】:How to dynamically create form controls in a form control and display them along other data within an ngFor?如何在表单控件中动态创建表单控件并将它们与 ngFor 中的其他数据一起显示?
【发布时间】:2021-10-29 20:58:26
【问题描述】:

我想在一个对象数组上运行一个 ngFor,以便用每个对象对应的数据填充标签,并且最好在同一个 ngFor 中,我想为上述数组中的每个对象添加一个表单控件。我还希望能够为每个添加的新对象添加一个新的表单控件。据我了解,执行上述操作的逻辑一切正常,我的问题是能够同时适当地循环对象数组和表单控件数组?

下面是为数组中的每个对象创建一个新的表单控件的逻辑:

首先,我在 ngOnInit 的 FormGroup 中初始化了 FormArray,如下所示:

stockForm: FormGroup;

ngOnInit(): void {
    this.stockForm = new FormGroup({
      'quantities': new FormArray([])
    })
    this.getBranchStock();
  }

然后我声明了两种方法,一种用于获取控件,另一种用于为上述 FormArray 创建控件。

提到的第一种方法(获取控件):

getQuantityControls() {
    return (<FormArray>this.stockForm.get('quantities')).controls;
  }

然后,提到的第二种方法(创建控件):

createNewQuantity() {
    const quantity = new FormControl('', [Validators.required]);
    (<FormArray>this.stockForm.get('quantities')).push(quantity)
  }

第二种方法“createNewQuantity”,将一个新的表单控件推送到表单数组。当我收到我之前谈到的对象数组时,最初会调用此方法。我通过 for 循环运行数组中的每个对象来调用“createNewQuantity”方法,如下所示:

product: BranchProduct[];

 getBranchStock() {
    const id = this.branchService.getBranchId();
    id.subscribe(
      (resp: any) => {
        this.subs.add(this.branchService.getBranchStock(resp).subscribe(
          (resp: any) => {
            this.product = resp;
            for (var i = 0; i < this.product.length; i++) {
              this.createNewQuantity();
            }
          },
          (error: HttpErrorResponse) => {
            console.log(error);
          })
        )
      })
  }

上述执行后,我对数组中的每个对象都有一个表单控件。这按预期工作(据我所知)。我真正的问题在于我运行 ngFor 循环的方式。如上所示,我需要遍历“产品”数组中的所有对象,以及“数量”FormArray 中的每个新创建的表单控件。我不知道如何设置模板以使其正常工作。我尝试过的如下:

<form [formGroup]="stockForm" *ngIf="stockForm">
              <mat-card *ngFor="let item of product; let quantity of getQuantityControls(); let i = index;" class="enter-quantity-card">
                  <mat-grid-list cols="5" rowHeight="7:1">
                    
                      <!-- Product Id Tile-->
                      <mat-grid-tile>
                        <div class="data-wrapper">
                          <h3>Product ID: <span class="data-text"><strong>{{item.ProductId}}</strong></span></h3>
                        </div>
                      </mat-grid-tile>

                      <!-- Product Type Tile -->
                      <mat-grid-tile>
                        <div class="data-wrapper">
                          <h3>Product Type: <span class="data-text"><strong>{{item.ProductTypeName}}</strong></span></h3>
                        </div>
                      </mat-grid-tile>

                      <!-- Product Name Tile-->
                      <mat-grid-tile>
                        <div class="data-wrapper">
                          <h3>Product Name: <span class="data-text"><strong>{{item.ProductName}}</strong></span></h3>
                        </div>
                      </mat-grid-tile>

                      <!-- Quantity On Hand Tile-->
                      <mat-grid-tile>
                        <div class="data-wrapper">
                          <h3>Quantity on Hand: <span class="data-text"><strong>{{item.QuantityOnHand}}</strong></span>
                          </h3>
                        </div>
                      </mat-grid-tile>

                      <!-- Quantity Selected Tile (Using Form Array) -->
                      <mat-grid-tile>
                        <mat-form-field>
                          <input matInput [formControlName]="i">
                        </mat-form-field>
                      </mat-grid-tile>

                  </mat-grid-list>
              </mat-card>
          </form>

由于我在 ONE ngFor 中同时拥有 let item of productlet quantity of getQuantityControls(); let i = index; 声明,因此上述内容不起作用。 Typescript 不允许这样做,因为新的 AbstractControl 不能是产品数组类型。但是,我根本不知道如何构建模板以使其正常工作。表单本身看起来像这样:

如您所见,每个对象“都有自己的”表单控件。但是我不知道如何使每个表单控件独一无二,以便分别验证每个控件。任何帮助表示赞赏。

【问题讨论】:

  • 如何使用index 而不是循环遍历product 数组来获取每个产品?你会有一个循环:*ngFor="let quantity of getQuantityControls(); let i = index;",然后像这样使用索引:{{product[i].ProductTypeName}}
  • 这很棒。简单的解决方法,非常感谢。我还需要在 ngFor 所在的同一 mat-card 标签中添加 formArrayName = "quantities"。如果您愿意,可以发表您的评论作为答案,我很乐意接受!

标签: arrays angular typescript forms ngfor


【解决方案1】:

如何使用index 而不是循环遍历product 数组来获取每个产品?

您将有一个循环:*ngFor="let quantity of getQuantityControls(); let i = index;",然后像这样使用index{{product[i].ProductTypeName}}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-02
    • 1970-01-01
    • 2021-03-21
    • 2012-02-27
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多