Angular中使用TanStack Table:如何在单元格中渲染组件?
在Angular中使用TanStack Table渲染自定义组件的通用方案
TanStack Table作为无头表格库,本身不直接提供类似ag-grid的cellRenderer配置,但可以结合Angular的动态组件加载能力实现通用的组件渲染方案,以下是具体步骤:
1. 扩展列定义,指定要渲染的组件
在列配置中通过meta字段添加自定义属性,标记当前列需要渲染的组件类:
import { ColumnDef } from '@tanstack/angular-table'; import { TextAndIconComponent } from './text-and-icon.component'; // 示例列定义 const columns: ColumnDef<YourRowType>[] = [ { id: 'textAndIcon', header: 'Index', meta: { cellComponent: TextAndIconComponent // 绑定要渲染的组件 } }, // 其他列配置... ];
2. 在表格模板中动态渲染组件
利用Angular的*ngComponentOutlet指令,在单元格位置动态加载组件,并传递行/列数据:
<table [tanStackTable]="table"> <thead> <tr *ngFor="let headerGroup of table.getHeaderGroups()"> <th *ngFor="let header of headerGroup.headers" [colspan]="header.colspan"> {{ header.column.columnDef.header }} </th> </tr> </thead> <tbody> <tr *ngFor="let row of table.getRowModel().rows"> <td *ngFor="let column of row.getVisibleColumns()"> <!-- 动态渲染自定义组件 --> <ng-container *ngIf="column.columnDef.meta?.cellComponent; else defaultCell" [ngComponentOutlet]="column.columnDef.meta.cellComponent" [ngComponentOutletInjector]="createCellInjector(row, column)"> </ng-container> <!-- 默认渲染逻辑(无组件时显示单元格值) --> <ng-template #defaultCell> {{ row.getValue(column.id) }} </ng-template> </td> </tr> </tbody> </table>
3. 实现组件数据注入
创建注入令牌,将行和列的数据传递给动态组件:
import { Injector, InjectionToken, Component } from '@angular/core'; import { TanStackTable, Row, Column } from '@tanstack/angular-table'; // 定义注入令牌,用于传递单元格数据 export const CELL_CONTEXT = new InjectionToken<{ row: Row<YourRowType>; column: Column<YourRowType> }>('CELL_CONTEXT'); @Component({ selector: 'app-your-table', templateUrl: './your-table.component.html' }) export class YourTableComponent { table: TanStackTable<YourRowType>; constructor(private injector: Injector) {} // 创建自定义注入器,传递行/列数据 createCellInjector(row: Row<YourRowType>, column: Column<YourRowType>): Injector { return Injector.create({ parent: this.injector, providers: [ { provide: CELL_CONTEXT, useValue: { row, column } } ] }); } }
4. 自定义组件接收数据
在自定义组件中注入CELL_CONTEXT,获取行数据并渲染:
import { Component, Inject } from '@angular/core'; import { CELL_CONTEXT } from './your-table.component'; import { Row } from '@tanstack/angular-table'; @Component({ template: ` <span>{{ (cellContext.row.index + 1).toFixed(0).padStart(2, String.fromCharCode(160)) }}</span> <mat-icon *ngIf="cellContext.row.original.isOpen" fontIcon="lock-open-right"></mat-icon> <mat-icon *ngIf="!cellContext.row.original.isOpen" fontIcon="lock"></mat-icon> ` }) export class TextAndIconComponent { constructor(@Inject(CELL_CONTEXT) public cellContext: { row: Row<YourRowType> }) {} }
关键说明
- 为什么
innerHTML不可行:Angular不会编译innerHTML中的组件标签,这类标签只会被当作纯HTML文本渲染,无法触发Angular组件的初始化和生命周期。 - 通用性:该方案支持渲染任意Angular组件,只需在列定义的
meta.cellComponent中指定对应组件类即可。
内容的提问来源于stack exchange,提问作者Jobu
相关产品推荐
相关产品推荐

