Angular如何在Material Table中动态渲染自定义组件并传递行数据
解决方案
你可以通过Angular提供的动态组件渲染能力解决这两个需求,步骤如下:
1. 调整泛型表格模板,预留动态组件容器
在你的Material Table列定义的mat-cell中,给自定义内容类型的列增加动态组件挂载容器:
<ng-container matColumnDef="{{col.objectField}}" *ngFor="let col of displayedColumns"> <mat-header-cell *matHeaderCellDef> {{col.title}} </mat-header-cell> <mat-cell *matCellDef="let row"> <!-- 原有普通字段、管道渲染逻辑保持不变 --> <ng-container *ngIf="col.contentMode === ContentMode.custom"> <ng-template #dynamicComponentContainer></ng-template> </ng-container> </mat-cell> </ng-container>
2. 在泛型表格组件类中实现动态组件渲染和数据传递
在表格组件中获取所有动态容器引用,根据行数据批量创建自定义组件并传入对应参数:
import { Component, Input, AfterViewInit, ViewChildren, QueryList, ViewContainerRef, ComponentRef } from '@angular/core'; // 引入你自定义的枚举、DTO等类型 import { ContentMode, TableColumnDto } from './your-type-definitions'; @Component({ selector: 'app-generic-material-table', templateUrl: './generic-material-table.component.html', styleUrls: ['./generic-material-table.component.scss'] }) export class GenericMaterialTableComponent implements AfterViewInit { @Input() dataSource: any[] = []; @Input() displayedColumns: TableColumnDto[] = []; // 把枚举暴露给模板使用 ContentMode = ContentMode; // 获取所有动态组件容器的引用 @ViewChildren('dynamicComponentContainer', { read: ViewContainerRef }) private dynamicContainers!: QueryList<ViewContainerRef>; ngAfterViewInit(): void { this.renderAllCustomComponents(); // 如果你的表格支持分页、排序、过滤,需要在数据源变更后重新调用该方法 } private renderAllCustomComponents(): void { // 清空所有容器避免重复渲染 this.dynamicContainers.forEach(container => container.clear()); // 遍历每一行、每一列配置,渲染自定义组件 this.dataSource.forEach((row, rowIndex) => { this.displayedColumns.forEach((col, colIndex) => { if (col.contentMode !== ContentMode.custom || !col.customContent) return; // 计算当前行当前列对应的容器索引 const containerIndex = rowIndex * this.displayedColumns.length + colIndex; const targetContainer = this.dynamicContainers.get(containerIndex); if (!targetContainer) return; // 创建自定义组件实例 const componentRef: ComponentRef<any> = targetContainer.createComponent(col.customContent); // 给自定义组件的@Input属性传值,这里按你的需求传行id即可,需要整行数据的话直接传row componentRef.instance.data = row.id; // 扩展:如果需要监听自定义组件的输出事件,在这里订阅即可 // componentRef.instance.deleteEvent.subscribe(() => handleDelete(row.id)) }); }); } }
3. 额外配置说明
- 你自定义的
TableButtonsComponent需要在所属模块的declarations数组中声明,Angular 9+不需要额外配置entryComponents - 如果你的自定义组件需要接收整行数据,直接修改组件的
@Input() data类型为对应的行DTO类型,然后上面的传值逻辑改成componentRef.instance.data = row即可
内容的提问来源于stack exchange,提问作者Bajo jajo
相关产品推荐
相关产品推荐

