首页 > 解决方案 > 在反应表单中手动设置表单数组元素的值

问题描述

这让我发疯,我已经为此不知所措,这是我完成这项工作的第二个整天,但仍然徒劳无功

我的表单值没有显示在 html 中我正在处理动态表,我事先不知道行数。问题是计算的总数不会显示在 html 中,即使它的值保存在组件对象中。

这是我的html代码

<table style="overflow-x: auto;display: inline-block; white-space: nowrap;">
    <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 formArrayName="products" *ngFor="let product of loanProductForm.get('products').controls; let i = index">
            <div [formGroupName]="i" 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" [id]="'productId' + i" 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' (keyup)="onPriceChange($event)" matInput formControlName="price"
                            [id]="'price' + i" name="" 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" [id]="'loanTermId' + i" 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" [id]="'quantity' + i" 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" [id]="'deposit' + i" 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" [id]="'total' + i" matInput name="total" id=""
                            placeholder="Total" style="color:black; font-weight:bold" required>
                        <!-- <input disabled type='number' [(ngModel)]="totalValue" ngModel [ngModelOptions]="{standalone: true}" [id]="'total' + i" matInput name="total" id="" placeholder="Total" style="color:black; font-weight:bold" required> -->
                    </mat-form-field>
                </td>

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

这是我的组件代码

this.loanProductForm = this._formBuilder.group({
      products: this._formBuilder.array([
        this.addProductFormGroup()
      ])
    });



 addProductButtonClick(): void {

    (<FormArray>this.loanProductForm.get('products')).push(this.addProductFormGroup());
    console.log('Loan Products: ', this.loanProductForm.value)

  }


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

即使它在我的文件中保存得很好,object但它没有在 html 中显示。计算总价值的公式是(价格*数量)- 存款=总额

这是我已经尝试过的,除此之外,我还尝试在form对象周围进行处理以查看值是否正在更改或不在表单中,它们接受更改object但未在 html 中显示

this.loanProductForm.valueChanges.subscribe((values) => {
  values.products.forEach(product => {
    product.total = (product.quantity * product.price) - product.deposit
  })

  console.log('Updated values of form are: ', values.products)
})

我只想更新total每一行中的值提前谢谢。试图完成这项工作让我筋疲力尽。再次提前感谢您的帮助

图片便于理解

标签: javascriptangularreactive-forms

解决方案


Well what you need is. When you create a form group you need to subscribe to changes and update the total value.

 addProductFormGroup(): FormGroup {
    const group = this._formBuilder.group({
      productId: ["", Validators.required],
      price: [0, Validators.required],
      loanTermId: ["", Validators.required],
      quantity: [0, Validators.required],
      deposit: [0, Validators.required],
      total: [0, Validators.required]
    });
    const quantity = group.get("quantity");
    const price = group.get("price");
    const deposit = group.get("deposit");
    const onChange = r => {
      if (r.price && r.quantity) {
        const total = r.price * r.quantity - r.deposit;
        group.patchValue(
          { total: total },
          { onlySelf: true, emitEvent: false } // emitEvent is crucial else it will cause and endless loop
        );
      }
    }; 
    group.valueChanges.subscribe(r => onChange(r));
    return group;
  }

Stackblitz example.


推荐阅读