Angular 6 material table 添加具有最后输入值的行(表单字段)

Angular 6 material table adds row(form field) with last entered value

我正在尝试添加表单字段并以 material table 的形式显示它。但是当我尝试添加一行(表单字段)时,它会显示带有最后输入值的表单字段(在本例中为 1 2 3)。我不知道我哪里出错了。希望有人能帮助我。提前致谢

下面是问题截图

下面是我的HTML代码

<button mat-raised-button color="primary" (click)="createNew()"> Add </button>
<form [formGroup]="fields" class="example-form">
<mat-table [dataSource]="dataSource">
    <ng-container matColumnDef="fieldName">
      <mat-header-cell *matHeaderCellDef> Field Name </mat-header-cell>
      <mat-cell *matCellDef="let row">
        <mat-form-field>
          <input formControlName="fieldName" placeholder="Field Name" matInput>
        </mat-form-field>
      </mat-cell>
    </ng-container>
    <ng-container matColumnDef="fieldType">
      <mat-header-cell *matHeaderCellDef> Field Type </mat-header-cell>
      <mat-cell *matCellDef="let row">
        <mat-form-field>
            <mat-select placeholder="Field Type">
                <mat-option *ngFor="let ft of fieldTypes" [value]="ft.value">
                  {{ft.value}}
                </mat-option>
              </mat-select>
        </mat-form-field>
      </mat-cell>
    </ng-container>
    <ng-container matColumnDef="fieldSize">
        <mat-header-cell *matHeaderCellDef> Field Size </mat-header-cell>
        <mat-cell *matCellDef="let row">
          <mat-form-field>
            <input formControlName="fieldSize" type="number" placeholder="Field Size" matInput>
          </mat-form-field>
        </mat-cell>
      </ng-container> 
    <ng-container matColumnDef="fieldOrder">
        <mat-header-cell *matHeaderCellDef> Field Order </mat-header-cell>
        <mat-cell *matCellDef="let row">
          <mat-form-field>
            <input formControlName="fieldOrder" type="number" placeholder="Field Order" matInput>
          </mat-form-field>
        </mat-cell>
      </ng-container>  
      <ng-container matColumnDef="actions">
        <mat-header-cell *matHeaderCellDef> Actions </mat-header-cell>
        <mat-cell *matCellDef="let row; let i = index">
          <button mat-raised-button color="warn" (click)="deleteRow(i)"> Delete </button>
        </mat-cell>
      </ng-container> 
    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
  </mat-table>
  <div class="buttonDiv">
    <button type="submit" mat-raised-button color="primary">Save</button>
  </div>  
  </form>

下面是我的 TS 代码

export class AppComponent {

  constructor(private fb: FormBuilder){}
  displayedColumns = ['fieldName', 'fieldType', 'fieldSize', 'fieldOrder', 'actions'];
  dataSource = new MatTableDataSource<Element>();
  element: Element; 

  fieldTypes = [
    {value: 'Date'},
    {value: 'Text'},
    {value: 'Radio'},
    {value: 'CheckBox'},
  ];
  createNew(){

    this.element= new Element();
    this.dataSource.data.push(this.element);
    this.dataSource._updateChangeSubscription();
  }

编辑 - 1

Stackblitz link - https://angular-ejtxrn.stackblitz.io/

除了 material table HTML,您可以了解 formArray 和 formGroup 的工作原理(根据 Angular.io 指南)...

添加按钮将添加行,保存后,您将看到数组的内容;请用以下 2 个代码替换您的 HTML 和 TS 文件...

component.html

<button mat-raised-button color="primary" (click)="createNew()"> Add </button>
<form [formGroup]="fields" class="example-form" (submit)="showData()">

  <div class='' formArrayName='elementArray' *ngFor="let item of fields.get('elementArray').controls; let i = index">
    <div [formGroupName]="i">
      <input type="text" formControlName="fieldName" placeholder="fieldName">

      <select formControlName="fieldType" placeholder="fieldType">
        <option *ngFor="let ft of fieldTypes" [value]="ft.value">
          {{ft.value}}
        </option>
      </select>

      <input type="number" formControlName="fieldSize" placeholder="fieldSizer">
      <input type="number" formControlName="fieldOrder" placeholder="fieldOrder">


      <!--
  <mat-table [dataSource]="dataSource">
      <ng-container matColumnDef="fieldName">
        <mat-header-cell *matHeaderCellDef> Field Name </mat-header-cell>
        <mat-cell *matCellDef="let row">
          <mat-form-field>
            <input formControlName="fieldName" placeholder="Field Name" matInput>
          </mat-form-field>
        </mat-cell>
      </ng-container>
      <ng-container matColumnDef="fieldType">
        <mat-header-cell *matHeaderCellDef> Field Type </mat-header-cell>
        <mat-cell *matCellDef="let row">
          <mat-form-field>
              <mat-select placeholder="Field Type">
                  <mat-option *ngFor="let ft of fieldTypes" [value]="ft.value">
                    {{ft.value}}
                  </mat-option>
                </mat-select>
          </mat-form-field>
        </mat-cell>
      </ng-container>
      <ng-container matColumnDef="fieldSize">
          <mat-header-cell *matHeaderCellDef> Field Size </mat-header-cell>
          <mat-cell *matCellDef="let row">
            <mat-form-field>
              <input formControlName="fieldSize" type="number" placeholder="Field Size" matInput>
            </mat-form-field>
          </mat-cell>
        </ng-container> 
      <ng-container matColumnDef="fieldOrder">
          <mat-header-cell *matHeaderCellDef> Field Order </mat-header-cell>
          <mat-cell *matCellDef="let row">
            <mat-form-field>
              <input formControlName="fieldOrder" type="number" placeholder="Field Order" matInput>
            </mat-form-field>
          </mat-cell>
        </ng-container>  
        <ng-container matColumnDef="actions">
          <mat-header-cell *matHeaderCellDef> Actions </mat-header-cell>
          <mat-cell *matCellDef="let row; let i = index">
            <button mat-raised-button color="warn" (click)="deleteRow(i)"> Delete </button>
          </mat-cell>
        </ng-container> 
      <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
      <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
    </mat-table>
    -->

    </div>
  </div>
  <div class="buttonDiv">
    <button type="submit" mat-raised-button color="primary">Save</button>

  </div>
</form>

<hr/>
<span *ngIf='messageText'>
    <h3>{{messageText}}</h3>
    <p *ngFor="let item of fields.value.elementArray">
      {{item.fieldName}} | {{item.fieldType}} | {{item.fieldSize}} | {{item.fieldOrder}}
    </p>
  </span>

component.ts

import { Component } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  title = 'OnboardingApp';
  messageText = '';
  constructor(private fb: FormBuilder){}
  displayedColumns = ['fieldName', 'fieldType', 'fieldSize', 'fieldOrder', 'actions'];
  dataSource = new MatTableDataSource<Element>();
  element: Element; 
  fields = this.fb.group({
    elementArray: this.fb.array([this.createElementData()])
  });
  fieldTypes = [
    {value: 'Date'},
    {value: 'Text'},
    {value: 'Radio'},
    {value: 'CheckBox'},
  ];

    createNew(){
      const newRow = this.createElementData();
      this.elementArray.push(newRow);
    }

  get elementArray(): FormArray{
    return this.fields.get("elementArray") as FormArray;
  }

createElementData():FormGroup{
        return this.fb.group({
            fieldName: [''],
            fieldType: [''],
            fieldSize: [''],
            fieldOrder: ['']
        });
    }

  deleteRow(index){
    /* console.log(index);
    const data = this.dataSource.data;
    console.log(data.splice(index,1));
    this.dataSource.data = data; */
    this.dataSource.data.splice(index,1);
    this.dataSource._updateChangeSubscription();
  }
  showData(){
    if (this.fields.value.elementArray.length>0){
      console.log(this.fields.value.elementArray);
      this.messageText = 'check console.log for the array or below';
    }
  }
}

export class Element{
  fieldName: string;
  fieldType: [];
  fieldSize: number;
  fieldOrder: number;
}