You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 14:05:19