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;
}
我正在尝试添加表单字段并以 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;
}