需要在 mat-table 中的每个新行上重新分配数据、分页器和排序
Need to reassign data, paginator, and sort on every new row in mat-table
我有一个 <mat-table>
,我在其中实现了一个 addRow()
函数,该函数使用一组基于数据类型的默认值在 table 中创建一个新行。
我遇到的问题是每次创建新行时,我都需要重新分配 MatTableDataSource
、MatPaginator
和 MatSort
。如果我不执行重新分配,则新数据不会显示,或者 pagination/sorting 不起作用。
所有这些重新分配看起来既昂贵又迂回,尤其是在较大的数据集上,但我不完全确定如何做得更好。
动态-table.component.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { TableField } from 'src/app/models/table-field';
const fields: TableField[] = [
{ name: "job", type: "string", editType: "free", options: [] },
{ name: "wage", type: "string", editType: "free", options: [] },
{ name: "state", type: "string", editType: "spinner", options: ["MI", "CA", "TX"] },
{ name: "isUnion", type: "boolean", editType: "checkbox", options: [] }
];
const rows: any[] = [
{ job: "J1", wage: "10.00", state: "MI", isUnion: false },
{ job: "J2", wage: "15.00", state: "TX", isUnion: true },
{ job: "J3", wage: "77.00", state: "CA", isUnion: true }
];
@Component({
selector: 'app-dynamic-table',
templateUrl: './dynamic-table.component.html',
styleUrls: ['./dynamic-table.component.css']
})
export class DynamicTableComponent implements OnInit {
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
@ViewChild(MatSort, { static: true }) sort: MatSort;
Fields: {}[];
Rows: {}[];
ColumnHeaders: string[];
dataSource: MatTableDataSource<{}>;
constructor() { }
ngOnInit() {
this.Fields = fields.map(field => field);
this.ColumnHeaders = this.Fields.map(field => field["name"]);
this.Rows = rows.map(row => row);
console.log(this.Fields);
console.log(this.Rows);
console.log(this.ColumnHeaders);
this.dataSource = new MatTableDataSource(rows);
}
ngAfterViewInit() {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
addRow() {
let row = {};
fields.forEach(field => {
switch(field.editType) {
case "free": {
row[field.name] = "default"
break;
}
case "spinner": {
row[field.name] = field.options[0];
break;
}
case "checkbox": {
row[field.name] = false;
break;
}
}
});
this.Rows = this.Rows.concat(row);
this.dataSource = new MatTableDataSource(this.Rows);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
printRows() {
console.log(this.dataSource.data)
}
}
动态-table.component.html
<table mat-table [dataSource]="dataSource" matSort>
<ng-container *ngFor="let field of Fields" matColumnDef="{{field.name}}">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{field.name}}</th>
<td mat-cell *matCellDef="let row">
<input *ngIf="field.editType == 'free'" matInput [(ngModel)]="row[field.name]" placeholder="{{row[field.name]}}" required>
<mat-select *ngIf="field.editType == 'spinner'" [(ngModel)]="row[field.name]">
<mat-option *ngFor="let option of field.options" [value]="option">{{option}}</mat-option>
</mat-select>
<mat-checkbox *ngIf="field.editType == 'checkbox'" [(ngModel)]="row[field.name]">
</mat-checkbox>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="ColumnHeaders"></tr>x
<tr mat-row *matRowDef="let row; columns: ColumnHeaders;"></tr>
</table>
<mat-paginator #paginator [pageSizeOptions]="[10, 20, 30]" showFirstLastButtons></mat-paginator>
<button mat-button color="primary" (click)="addRow()">Add Row</button>
<button mat-button color="primary" (click)="printRows()">Print Rows</button>
您可以使用 setter 进行分页和排序组件
@ViewChild(MatPaginator, { static: false })
set paginator(value: MatPaginator) {
if(this.dataSource) {
this.dataSource.paginator = value;
}
}
@ViewChild(MatSort, { static: false })
set sort(value: MatSort) {
if(this.dataSource) {
this.dataSource.sort = value;
}
}
您可以在此处删除分配:
ngAfterViewInit() {
//this.dataSource.paginator = this.paginator;
//this.dataSource.sort = this.sort;
}
要修改 table 您别无选择,只能重新分配数据源。
添加新行时,只需修改数据源即可。感谢 setter,分页器和排序组件将得到更新。
addRow() {
let row = {};
fields.forEach(field => {
switch(field.editType) {
case "free": {
row[field.name] = "default"
break;
}
case "spinner": {
row[field.name] = field.options[0];
break;
}
case "checkbox": {
row[field.name] = false;
break;
}
}
});
this.Rows = this.Rows.concat(row);
this.dataSource.data = this.Rows;
}
我有一个 <mat-table>
,我在其中实现了一个 addRow()
函数,该函数使用一组基于数据类型的默认值在 table 中创建一个新行。
我遇到的问题是每次创建新行时,我都需要重新分配 MatTableDataSource
、MatPaginator
和 MatSort
。如果我不执行重新分配,则新数据不会显示,或者 pagination/sorting 不起作用。
所有这些重新分配看起来既昂贵又迂回,尤其是在较大的数据集上,但我不完全确定如何做得更好。
动态-table.component.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { TableField } from 'src/app/models/table-field';
const fields: TableField[] = [
{ name: "job", type: "string", editType: "free", options: [] },
{ name: "wage", type: "string", editType: "free", options: [] },
{ name: "state", type: "string", editType: "spinner", options: ["MI", "CA", "TX"] },
{ name: "isUnion", type: "boolean", editType: "checkbox", options: [] }
];
const rows: any[] = [
{ job: "J1", wage: "10.00", state: "MI", isUnion: false },
{ job: "J2", wage: "15.00", state: "TX", isUnion: true },
{ job: "J3", wage: "77.00", state: "CA", isUnion: true }
];
@Component({
selector: 'app-dynamic-table',
templateUrl: './dynamic-table.component.html',
styleUrls: ['./dynamic-table.component.css']
})
export class DynamicTableComponent implements OnInit {
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
@ViewChild(MatSort, { static: true }) sort: MatSort;
Fields: {}[];
Rows: {}[];
ColumnHeaders: string[];
dataSource: MatTableDataSource<{}>;
constructor() { }
ngOnInit() {
this.Fields = fields.map(field => field);
this.ColumnHeaders = this.Fields.map(field => field["name"]);
this.Rows = rows.map(row => row);
console.log(this.Fields);
console.log(this.Rows);
console.log(this.ColumnHeaders);
this.dataSource = new MatTableDataSource(rows);
}
ngAfterViewInit() {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
addRow() {
let row = {};
fields.forEach(field => {
switch(field.editType) {
case "free": {
row[field.name] = "default"
break;
}
case "spinner": {
row[field.name] = field.options[0];
break;
}
case "checkbox": {
row[field.name] = false;
break;
}
}
});
this.Rows = this.Rows.concat(row);
this.dataSource = new MatTableDataSource(this.Rows);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
printRows() {
console.log(this.dataSource.data)
}
}
动态-table.component.html
<table mat-table [dataSource]="dataSource" matSort>
<ng-container *ngFor="let field of Fields" matColumnDef="{{field.name}}">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{field.name}}</th>
<td mat-cell *matCellDef="let row">
<input *ngIf="field.editType == 'free'" matInput [(ngModel)]="row[field.name]" placeholder="{{row[field.name]}}" required>
<mat-select *ngIf="field.editType == 'spinner'" [(ngModel)]="row[field.name]">
<mat-option *ngFor="let option of field.options" [value]="option">{{option}}</mat-option>
</mat-select>
<mat-checkbox *ngIf="field.editType == 'checkbox'" [(ngModel)]="row[field.name]">
</mat-checkbox>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="ColumnHeaders"></tr>x
<tr mat-row *matRowDef="let row; columns: ColumnHeaders;"></tr>
</table>
<mat-paginator #paginator [pageSizeOptions]="[10, 20, 30]" showFirstLastButtons></mat-paginator>
<button mat-button color="primary" (click)="addRow()">Add Row</button>
<button mat-button color="primary" (click)="printRows()">Print Rows</button>
您可以使用 setter 进行分页和排序组件
@ViewChild(MatPaginator, { static: false })
set paginator(value: MatPaginator) {
if(this.dataSource) {
this.dataSource.paginator = value;
}
}
@ViewChild(MatSort, { static: false })
set sort(value: MatSort) {
if(this.dataSource) {
this.dataSource.sort = value;
}
}
您可以在此处删除分配:
ngAfterViewInit() {
//this.dataSource.paginator = this.paginator;
//this.dataSource.sort = this.sort;
}
要修改 table 您别无选择,只能重新分配数据源。 添加新行时,只需修改数据源即可。感谢 setter,分页器和排序组件将得到更新。
addRow() {
let row = {};
fields.forEach(field => {
switch(field.editType) {
case "free": {
row[field.name] = "default"
break;
}
case "spinner": {
row[field.name] = field.options[0];
break;
}
case "checkbox": {
row[field.name] = false;
break;
}
}
});
this.Rows = this.Rows.concat(row);
this.dataSource.data = this.Rows;
}