Angular Material 表动态列
Posted
技术标签:
【中文标题】Angular Material 表动态列【英文标题】:Angular Material table dynamic columns 【发布时间】:2020-06-10 20:40:26 【问题描述】:我创建了 mat-table 组件,它通过我粘贴的数据生成动态列,但没有操作图标。
<table mat-table [dataSource]="data" class="mat-elevation-z8">
<ng-container [matColumnDef]="item.columnDef" *ngFor="let item of columns; let i = index">
<th mat-header-cell *matHeaderCellDef> item.header </th>
<td mat-cell *matCellDef="let element"> element[item.columnDef] </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
Input() 从另一个组件粘贴数据。
columns: Column [] = [
columnDef: 'faculty_id', header: 'ID',
columnDef: 'faculty_name', header: 'Faculty',
columnDef: 'faculty_description', header: 'Description',
columnDef: 'action', header: 'Actions', actions: [
type: tableActionsType.Edit, icon: 'edit', matTooltip: 'Edit',
type: tableActionsType.Delete, icon: 'delete', matTooltip: 'Delete'
]
];
我需要什么:
我想用图标生成列Actions,
-
问题:
我需要在 item.columnDef === 'action'
时检查此循环 *ngFor="let item of columns;
并渲染 mat-icon
<ng-container [matColumnDef]="item.columnDef" *ngFor="let item of columns; let i = index">
<th mat-header-cell *matHeaderCellDef> item.header </th>
<td mat-cell *matCellDef="let element">
// if item.columnDef == 'action' then mat-icon
// else element[item.columnDef]
<mat-icon aria-hidden="false" aria-label="edit" *ngFor="let icon of item.actions" [matTooltip]="icon.matTooltip" (click)="check()">icon.icon</mat-icon>
</td>
</ng-container>
【问题讨论】:
有关于这个问题的更新吗? @Entertain 是的,我设法解决了。请查看答案。 【参考方案1】:另一种解决方案
您可以使用 [ngSwitch] 自定义每个动态列的列内容
<table cdk-table [dataSource]="datasource | async">
<ng-container *ngFor="let col of columnsToDisplay | async">
<ng-container [ngSwitch]="col.id">
**Action Column**
<ng-container *ngSwitchCase="'_action'" cdkColumnDef="_action">
<th cdk-header-cell *cdkHeaderCellDef>col.name</th>
<td cdk-cell *cdkCellDef="let row">
<ng-container *ngTemplateOutlet="#actionTemplate; context: row: row"> </ng-container>
</td>
</ng-container>
**All another column**
<ng-container *ngSwitchDefault cdkColumnDef="col.id">
<th cdk-header-cell *cdkHeaderCellDef>col.name</th>
<td cdk-cell *cdkCellDef="let row">row[col.id]</td>
</ng-container>
</ng-container>
</ng-container>
<tr cdk-header-row *cdkHeaderRowDef="columnsIDs | async"></tr>
<tr cdk-row *cdkRowDef="let row; columns: (columnsIDs | async)"></tr>
</table>
以及动作栏模板
<ng-template
#actionTemplate
let-row="row"
>
<button
[matMenuTriggerFor]="menu">
</button>
<mat-menu #menu="matMenu">
<button></button>
</mat-menu>
</ng-template>
【讨论】:
【参考方案2】:所以我做出了这个决定。对我来说效果很好。
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" matSort>
<ng-container [matColumnDef]="item.columnDef" *ngFor="let item of columns; let i = index">
<th mat-header-cell *matHeaderCellDef mat-sort-header [disabled]="item.columnDef=='action'? true : false "> item.header </th>
<ng-container *ngIf="!item.actions"> // *if column is not the action column then render normal column
<td mat-cell *matCellDef="let element; let i = index"> item.header =='ID' ? matPaginator.pageSize * matPaginator.pageIndex + i + 1 : element[item.columnDef] </td>
</ng-container>
<td mat-cell *matCellDef="let element" class="action-link">
// *rendering actions in the action column for instance it can be edit or delete
<mat-icon aria-hidden="false" [attr.aria-label]='action.aria_label' *ngFor="let action of item.actions" [matTooltip]="action.matTooltip" (click)="getEvent(action,element)">action.icon</mat-icon>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
【讨论】:
以上是关于Angular Material 表动态列的主要内容,如果未能解决你的问题,请参考以下文章
如何为已知行数创建具有无限列的 Angular Material Design 表?
在 React Material UI Table 中创建动态操作列