带有动态复选框的 CDK Angular Table 找不到正确的列名称
CDK Angular Table with dynamic checkboxes not finding correct column names
我有一个动态 CDK Angular Material mat-table,我已经修复了 mat-checkbox。它正在填充数据,但不允许我设置正确的列 headers。显示的所有内容都来自 UserInformation 数组的 key:value 对。但是,我需要设置第二个数组来显示正确的 header 名称,因为我无法控制来自 API 的键名,需要在 TypeScript 中设置它们。并非所有来自 API 的信息都会显示在 table 中。我也会有多个 tables 并且需要使它完全可重用到显示内容将在 TypeScript 中更改的位置,其他所有内容都将被注入。
现在我只想让显示的列名称在 table 中正确显示。
//Dummy Data
const UserInformation: any[] = [
{
'firstName': 'Jane',
'lastName': 'Doe',
'jobRole': 'My Job',
'company': 'Work',
'status': true,
'employeeID': '23456',
'phone': '(253)227-2567',
'email': 'myemail@myemail.com'
},
{
'firstName': 'John',
'lastName': 'Smith',
'jobRole': 'My Job',
'company': 'Work',
'status': true,
'employeeID': '23456',
'phone': '(253)227-2567',
'email': 'myemail@myemail.com'
}
];
columns: any;
// Material Table Columns
@Input() public content: any;
public rows = new MatTableDataSource<any>();
headers = [
{ filed: '',
},
{ field: 'firstName',
title: 'First Name',
cell: (element: any) => `${element.firstName}`,
},
{ field: 'lastName',
title: 'Last Name',
cell: (element: any) => `${element.lastName}`,
},
{ field: 'employeeID',
title: 'Employee ID',
cell: (element: any) => `${element.employeeID}`,
},
{ field: 'jobRole',
title: 'Job Role',
cell: (element: any) => `${element.jobRole}`,
},
{ field: 'email',
title: 'Email',
cell: (element: any) => `${element.email}`,
}
];
displayedColumns = this.headers.map(c => c.field);
public selection = new SelectionModel<any>(true, []);
// Material Table Functionality
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
@ViewChild('tableResults') tableResults;
this.showUsers();
// Material Table
public filterBy(event: any): void {
const filterBy: string = event.target.value;
this.rows.filter = filterBy;
}
public isAllSelected() {
const numSelected = this.selection.selected.length;
const numRows = this.rows.data.length;
return numSelected === numRows;
}
public masterToggle() {
this.isAllSelected() ?
this.selection.clear() :
this.rows.data.forEach(row => this.selection.select(row));
}
public checkboxLabel(row?: any): string {
return (!row)
? `${this.isAllSelected() ? 'select' : 'deselect'} all`
: `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;
}
private updateRows(): void {
this.rows = new MatTableDataSource<any>(this.displayedColumns);
this.rows.sort = this.sort;
this.rows.paginator = this.paginator;
}
private updateColumns(): void {
this.columns = ['select'];
for (const column of Object.keys(this.displayedColumns[0])) {
this.columns.push(column);
}
}
private updateTable(): void {
if (this.displayedColumns) {
this.updateRows();
this.updateColumns();
}
}
public showUsers(): void {
this.displayedColumns = UserInformation;
this.updateTable();
this.selection.clear();
}
item1() {
alert('solved!!');
// this.target.classList.add('class3');
}
dragStarted(event: CdkDragStart<string[]>, index: number ) {
if (event) {
this.previousIndex = index;
}
}
dropListDropped(event: CdkDropList<string[]>, index: number) {
if (event) {
moveItemInArray(this.columns, this.previousIndex, index);
}
}
//HTML TABLE
<mat-table [dataSource]="rows" class="mat-elevation-z8" cdkDropListGroup matSort matSortActive="symbol" matSortDirection="asc">
<ng-container *ngFor="let column of columns; let i = index" matColumnDef="{{column}}">
<span *ngIf="i === 0">
<mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()"
[aria-label]="checkboxLabel()">
</mat-checkbox>
</mat-header-cell>
<mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)"
[aria-label]="checkboxLabel(row)">
</mat-checkbox>
</mat-cell>
</span>
<span *ngIf="i !== 0">
<mat-header-cell *matHeaderCellDef
cdkDropList
cdkDropListLockAxis="x"
cdkDropListOrientation="horizontal"
(cdkDropListDropped)="dropListDropped($event, i)"
cdkDrag
(cdkDragStarted)="dragStarted($event, i)"
[cdkDragData]="{name: column, columIndex: i}"
mat-sort-header>
{{ column }}
</mat-header-cell>
<mat-cell *matCellDef="let row" > {{ row[column] }} </mat-cell>
</span>
</ng-container>
<mat-header-row *matHeaderRowDef="columns; sticky: true;"></mat-header-row>
<mat-row *matRowDef="let row; columns: columns;" (click)="selection.toggle(row)" [routerLink]="['']"></mat-row>
</mat-table>
<mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
抱歉,这是很多代码,但是 table 中发生了很多事情。我真的只是希望得到正确的指示,让 "header" 中列出的 table headers 连接到 displayedColumns 以显示在 table header 而不是 UserInformation 数组中的值。非常感谢任何帮助。
无需为 headers 使用额外的数组,只需在 mat-header-cell
中添加一个管道即可将键转换为显示的值。
例如,参见此 Stackblitz。
我有一个动态 CDK Angular Material mat-table,我已经修复了 mat-checkbox。它正在填充数据,但不允许我设置正确的列 headers。显示的所有内容都来自 UserInformation 数组的 key:value 对。但是,我需要设置第二个数组来显示正确的 header 名称,因为我无法控制来自 API 的键名,需要在 TypeScript 中设置它们。并非所有来自 API 的信息都会显示在 table 中。我也会有多个 tables 并且需要使它完全可重用到显示内容将在 TypeScript 中更改的位置,其他所有内容都将被注入。
现在我只想让显示的列名称在 table 中正确显示。
//Dummy Data
const UserInformation: any[] = [
{
'firstName': 'Jane',
'lastName': 'Doe',
'jobRole': 'My Job',
'company': 'Work',
'status': true,
'employeeID': '23456',
'phone': '(253)227-2567',
'email': 'myemail@myemail.com'
},
{
'firstName': 'John',
'lastName': 'Smith',
'jobRole': 'My Job',
'company': 'Work',
'status': true,
'employeeID': '23456',
'phone': '(253)227-2567',
'email': 'myemail@myemail.com'
}
];
columns: any;
// Material Table Columns
@Input() public content: any;
public rows = new MatTableDataSource<any>();
headers = [
{ filed: '',
},
{ field: 'firstName',
title: 'First Name',
cell: (element: any) => `${element.firstName}`,
},
{ field: 'lastName',
title: 'Last Name',
cell: (element: any) => `${element.lastName}`,
},
{ field: 'employeeID',
title: 'Employee ID',
cell: (element: any) => `${element.employeeID}`,
},
{ field: 'jobRole',
title: 'Job Role',
cell: (element: any) => `${element.jobRole}`,
},
{ field: 'email',
title: 'Email',
cell: (element: any) => `${element.email}`,
}
];
displayedColumns = this.headers.map(c => c.field);
public selection = new SelectionModel<any>(true, []);
// Material Table Functionality
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
@ViewChild('tableResults') tableResults;
this.showUsers();
// Material Table
public filterBy(event: any): void {
const filterBy: string = event.target.value;
this.rows.filter = filterBy;
}
public isAllSelected() {
const numSelected = this.selection.selected.length;
const numRows = this.rows.data.length;
return numSelected === numRows;
}
public masterToggle() {
this.isAllSelected() ?
this.selection.clear() :
this.rows.data.forEach(row => this.selection.select(row));
}
public checkboxLabel(row?: any): string {
return (!row)
? `${this.isAllSelected() ? 'select' : 'deselect'} all`
: `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;
}
private updateRows(): void {
this.rows = new MatTableDataSource<any>(this.displayedColumns);
this.rows.sort = this.sort;
this.rows.paginator = this.paginator;
}
private updateColumns(): void {
this.columns = ['select'];
for (const column of Object.keys(this.displayedColumns[0])) {
this.columns.push(column);
}
}
private updateTable(): void {
if (this.displayedColumns) {
this.updateRows();
this.updateColumns();
}
}
public showUsers(): void {
this.displayedColumns = UserInformation;
this.updateTable();
this.selection.clear();
}
item1() {
alert('solved!!');
// this.target.classList.add('class3');
}
dragStarted(event: CdkDragStart<string[]>, index: number ) {
if (event) {
this.previousIndex = index;
}
}
dropListDropped(event: CdkDropList<string[]>, index: number) {
if (event) {
moveItemInArray(this.columns, this.previousIndex, index);
}
}
//HTML TABLE
<mat-table [dataSource]="rows" class="mat-elevation-z8" cdkDropListGroup matSort matSortActive="symbol" matSortDirection="asc">
<ng-container *ngFor="let column of columns; let i = index" matColumnDef="{{column}}">
<span *ngIf="i === 0">
<mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()"
[aria-label]="checkboxLabel()">
</mat-checkbox>
</mat-header-cell>
<mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)"
[aria-label]="checkboxLabel(row)">
</mat-checkbox>
</mat-cell>
</span>
<span *ngIf="i !== 0">
<mat-header-cell *matHeaderCellDef
cdkDropList
cdkDropListLockAxis="x"
cdkDropListOrientation="horizontal"
(cdkDropListDropped)="dropListDropped($event, i)"
cdkDrag
(cdkDragStarted)="dragStarted($event, i)"
[cdkDragData]="{name: column, columIndex: i}"
mat-sort-header>
{{ column }}
</mat-header-cell>
<mat-cell *matCellDef="let row" > {{ row[column] }} </mat-cell>
</span>
</ng-container>
<mat-header-row *matHeaderRowDef="columns; sticky: true;"></mat-header-row>
<mat-row *matRowDef="let row; columns: columns;" (click)="selection.toggle(row)" [routerLink]="['']"></mat-row>
</mat-table>
<mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
抱歉,这是很多代码,但是 table 中发生了很多事情。我真的只是希望得到正确的指示,让 "header" 中列出的 table headers 连接到 displayedColumns 以显示在 table header 而不是 UserInformation 数组中的值。非常感谢任何帮助。
无需为 headers 使用额外的数组,只需在 mat-header-cell
中添加一个管道即可将键转换为显示的值。
例如,参见此 Stackblitz。