以角反应形式创建角表

问题描述 投票:0回答:1

我正在尝试使用Angular Material中的反应形式创建表。问题是我如何实现一种功能,当您单击“添加行”按钮时,它将自动添加行,您可以在其中输入字段。

Please see this stackblitz link

createForm() {
  this.form = this.fb.group({
    products: this.fb.array([]),
  });
}

addRow() {
  const rows = this.form.get('products') as FormArray;
  rows.push(
    this.fb.group({
      product_id: [null],
    })
  );
}
angular angular-material angular8 angular-reactive-forms angular-forms
1个回答
1
投票

您可以按照以下步骤进行

  1. FormArray中的输入应具有唯一的ID
  2. 数据表需要trackBy以避免行操作错误
  3. 要更新数据表,请使用table.renderRows();

example

    <form [formGroup]="form">

      <mat-card class="mat-elevation-z8">

        <mat-table
          #table
          class="mat-elevation-z0"
          [dataSource]="dataSource" [trackBy]="trackRows">

          <!-- Product Column -->
          <ng-container matColumnDef="product">
            <!-- <mat-header-cell *matHeaderCellDef>Product</mat-header-cell> -->
            <mat-cell *matCellDef="let row; let i = index"> 
              <ng-container [formGroup]="row">
                <mat-form-field>
                  <mat-label>Product</mat-label>
                  <input matInput placeholder="Product"
                    id="product_id_{{i}}"
                    name="product_id_{{i}}"
                    formControlName="product_id" required />
                </mat-form-field>
              </ng-container>
            </mat-cell>
          </ng-container>

          <!-- Product Column -->
          <ng-container matColumnDef="unit">
            <!-- <mat-header-cell *matHeaderCellDef>Unit</mat-header-cell> -->
            <mat-cell *matCellDef="let row; let i = index"> 
              <ng-container [formGroup]="row">
                <mat-form-field>
                  <mat-label>Unit</mat-label>
                  <input matInput placeholder="Unit"
                    id="product_id_{{i}}"
                    name="product_id_{{i}}"
                    formControlName="unit" required />
                </mat-form-field>
              </ng-container>
            </mat-cell>
          </ng-container>

          <!-- Header Declarations -->
          <!-- 
          <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
          -->

          <!-- Row Declarations -->
          <mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
        </mat-table>

        <mat-card-actions>
          <button mat-raised-button color="primary"
            (click)="createRow()">
            <mat-icon>add</mat-icon>
            Add New
          </button>
        </mat-card-actions>

      </mat-card>
    </form>

    import { Component, ViewChild } from '@angular/core';
    import { FormGroup, FormBuilder, Validators, FormArray, AbstractControl } from '@angular/forms';
    import { MatTable, MatTableDataSource } from '@angular/material/table';

    @Component({
      selector: 'table-basic-example',
      styleUrls: ['table-basic-example.css'],
      templateUrl: 'table-basic-example.html',
    })
    export class TableBasicExample {
      form: FormGroup;
      private formSubmitAttempt: boolean;
      private uid = 0;

      @ViewChild('table') table: MatTable<any>;

      displayedColumns = ['product', 'unit'];
      dataSource: MatTableDataSource<AbstractControl>;

      get productControlArray() {
        return this.form.get('products') as FormArray;
      }

      constructor(private fb: FormBuilder) {
        this.createForm();
        this.addRow();
        this.dataSource = new MatTableDataSource(
          this.productControlArray.controls);
      }

      createForm() {
        this.form = this.fb.group({
          products: this.fb.array([]),
        });
      }

      trackRows(index: number, row: AbstractControl) {
        return row.value.uid;
      }

      private addRow() {
        const rows = this.productControlArray;
        rows.push(
          this.fb.group({
            uid: this.nextUid(),
            product_id: [undefined, Validators.required],
            unit: [0, Validators.required]
          })
        );
      }

      createRow() {
        this.addRow();
        this.table.renderRows();
      }

      private nextUid() {
        ++this.uid
        return this.uid;
      }
    }
© www.soinside.com 2019 - 2024. All rights reserved.