动态添加行:Angular 响应式表单

5

当我点击按钮时,我想动态添加行。我使用响应式表单实现此功能。 这是我所说的

这是我的HTML代码:

<table>
    <thead>
        <tr class='tableHeader'>
            <div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
                <td fxFlex="22" class="pr-4">Name</td>
                <td fxFlex="15" class="pr-4">Price</td>
                <td fxFlex="15" class="pr-4">Loan Term</td>
                <td fxFlex="15" class="pr-4">Quantity</td>
                <td fxFlex="15" class="pr-4">Deposit</td>
                <td fxFlex="15" class="pr-4">Total</td>
            </div>
        </tr>
    </thead>
    <tbody>
        <tr [formGroup]="loanProductForm">
            <div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
                <td fxFlex="22">
                    <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                        <mat-label>Product </mat-label>
                        <mat-select formControlName="productId" required>
                            <mat-option *ngFor="let product of productList" [value]="product.productId">
                                {{product.name}}
                            </mat-option>
                        </mat-select>
                    </mat-form-field>
                </td>
                <td fxFlex="15">
                    <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                        <mat-label>Price </mat-label>
                        <input type='number' matInput formControlName="price" name="" id="" placeholder="Price" required>
                    </mat-form-field>
                </td>
                <td fxFlex="15">
                    <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                        <mat-label>Loan Term </mat-label>
                        <mat-select formControlName="loanTermId" required>
                            <mat-option *ngFor="let loanTerm of loanTermList" [value]="loanTerm.loanTermId">
                                {{loanTerm.numberOfMonths}}
                            </mat-option>
                        </mat-select>
                    </mat-form-field>
                </td>
                <td fxFlex="15">
                    <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                        <mat-label>Quantity </mat-label>
                        <input type='number' formControlName="quantity" matInput name="" id="" placeholder="Quantity" required>
                    </mat-form-field>
                </td>
                <td fxFlex="15">
                    <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                        <mat-label>Deposit </mat-label>
                        <input type='number' formControlName="deposit" matInput name="" id="" placeholder="Deposit" required>
                    </mat-form-field>
                </td>
                <td fxFlex="15">
                    <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                        <mat-label>Total </mat-label>
                        <input type='number' formControlName="total" matInput name="" id="" placeholder="Total" required>
                    </mat-form-field>
                </td>

            </div>
        </tr>
        <tr>
            <td fxFlex="10">
                <div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
                    <button mat-stroked-button class='addBtn btn-style-2' fxFlex='100' (click)='addTableRow()'>Add
                        <mat-icon matSuffix>add_box</mat-icon>
                    </button>
                </div>
            </td>
        </tr>
    </tbody>
</table>

以下是我在我的ts文件中尝试的方式:

   this.loanProductForm = this._formBuilder.group({
      productId: ['', Validators.required],
      price: ['', Validators.required],
      loanTermId: ['', Validators.required],
      quantity: ['', Validators.required],
      deposit: ['', Validators.required],
      total: ['', Validators.required],
    })


addTableRow() {
    this.newRow = { productId: '', price: '', loanTermId: '', quantity: '', deposit: '', total: '' };
    // this.tableRows.push(this.newRow)
  }

但是代码不允许我在这个表单上使用push方法。


我猜你是指响应式表单吧? - Dipak Telangre
是的,完全正确。抱歉,我打错了,我只是在更正它。 - Lint
添加另一行表单还是将表单值作为一行添加? - GaryB
我的意思是,“添加”按钮将在下方插入一行新的数据。 - Lint
新的数值行还是新的输入行? - GaryB
你应该使用FormArray,https://medium.com/@mustafakunwa/reactive-form-in-angular-with-formarray-2595e5ee1d31 - Mustafa Kunwa
3个回答

6
在这种情况下,您需要使用表单数组。
试试这样做: 工作演示 .ts
this.loanProductForm = this.fb.group({
  products: this.fb.array([
    this.addProductFormGroup()
  ])
});

 addProductFormGroup(): FormGroup {
    return this.fb.group({
      productId: ['', Validators.required],
      price: ['', Validators.required],
      loanTermId: ['', Validators.required],
      quantity: ['', Validators.required],
      deposit: ['', Validators.required],
      total: ['', Validators.required],
    });
  }

addProductButtonClick(): void {
   (<FormArray>this.loanProductForm.get('products')).push(this.addProductFormGroup());
}

.html

 <button type="button" (click)="addProductButtonClick()">
          Add Product
 </button>

我在你的第二段代码中遇到了错误。 找不到名称“addProductFormGroup”。 我应该在哪里编写这段代码? 我将其编写在您的formBuilder组下方。 - Lint
这是一个单独的函数。 - Adrita Sharma
@Lint从这里开始采取方法并在您的项目中实现,也要查看HTML。 - Adrita Sharma
1
现在它能工作了,但是有一个小问题就是当我点击添加按钮时,新行立即变为红色(就像表单无效的情况一样),为了避免这个问题。 - Lint
我已经在演示中添加了它。 - Adrita Sharma
显示剩余12条评论

3

这个链接已经失效。 - Lint
抱歉。已修复。 - irudji

1

您需要使用表单数组而不是表单组:

ts

  ...

       this.loanProductForm = this._formBuilder.group(
           loanProductArray : this._formBuilder.array([this.buildGroup()])
    ) ;


    get loanProductArray(){
      return this.loanProductForm.get('loanProductArray ') as FormArray ;
    }

    buildGroup(){
    return    this.loanProductForm = this._formBuilder.group({
          productId: ['', Validators.required],
          price: ['', Validators.required],
          loanTermId: ['', Validators.required],
          quantity: ['', Validators.required],
          deposit: ['', Validators.required],
          total: ['', Validators.required],
        })
    }

addTableRow() {
   this.loanProductArray.push(this.buildGroup()) ;
  }

html

    ...

 <tbody [formGroup]="loanProductForm">
   <ng-container formArrayName="loanProductArray">
        <tr *ngFor="let line of loanProductArray.controls; let i=index" [formGroupName]="i">
            <div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
                <td fxFlex="22">
                    <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                        <mat-label>Product </mat-label>
                        <mat-select formControlName="productId" required>
                            <mat-option *ngFor="let product of productList" [value]="product.productId">
                                {{product.name}}
                            </mat-option>
                        </mat-select>
                    </mat-form-field>
                </td>
                <td fxFlex="15">
                    <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                        <mat-label>Price </mat-label>
                        <input type='number' matInput formControlName="price" name="" id="" placeholder="Price" required>
                    </mat-form-field>
                </td>
                <td fxFlex="15">
                    <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                        <mat-label>Loan Term </mat-label>
                        <mat-select formControlName="loanTermId" required>
                            <mat-option *ngFor="let loanTerm of loanTermList" [value]="loanTerm.loanTermId">
                                {{loanTerm.numberOfMonths}}
                            </mat-option>
                        </mat-select>
                    </mat-form-field>
                </td>
                <td fxFlex="15">
                    <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                        <mat-label>Quantity </mat-label>
                        <input type='number' formControlName="quantity" matInput name="" id="" placeholder="Quantity" required>
                    </mat-form-field>
                </td>
                <td fxFlex="15">
                    <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                        <mat-label>Deposit </mat-label>
                        <input type='number' formControlName="deposit" matInput name="" id="" placeholder="Deposit" required>
                    </mat-form-field>
                </td>
                <td fxFlex="15">
                    <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                        <mat-label>Total </mat-label>
                        <input type='number' formControlName="total" matInput name="" id="" placeholder="Total" required>
                    </mat-form-field>
                </td>

            </div>
        </tr>
        <tr>
            <td fxFlex="10">
                <div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
                    <button mat-stroked-button class='addBtn btn-style-2' fxFlex='100' (click)='addTableRow()'>Add
                        <mat-icon matSuffix>add_box</mat-icon>
                    </button>
                </div>
            </td>
        </tr>
</<ng-container>
    </tbody>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接