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

Angular12自定义表格组件如何从ts文件设置td动态内容

问题原因

Angular的模板语法(包括{{}}插值表达式、routerLink等内置指令)只会在编译阶段被解析处理,你通过innerHTML传入的内容属于运行时插入的纯字符串,不会经过Angular编译器的处理,因此只会作为普通文本/静态HTML渲染,既无法解析插值语法拿到变量值,也无法激活路由、事件绑定等Angular能力。

推荐解决方案:使用ngTemplateOutlet实现自定义内容插槽

这是Angular生态里封装动态内容组件的标准方案,实现成本低、兼容性好,支持所有原生Angular模板能力:

步骤1:改造自定义表格组件

首先修改ColumnItem类型定义,新增模板引用属性:

// table.component.ts
import { TemplateRef } from '@angular/core';

export interface ColumnItem {
  name: string;
  sortOrder: 'ascend'|'descend'|null;
  sortDirections: ('ascend'|'descend'|null)[];
  columnKey: string;
  // 新增属性,接收外部传入的自定义单元格模板
  tdTemplate?: TemplateRef<{$implicit: any}>;
}

接着修改表格组件模板,使用ngTemplateOutlet渲染自定义内容:

<!-- table.component.html -->
<thead>
  <tr>
    <th *ngFor="let column of listOfColumns">
      {{ column.name }}
    </th>
  </tr>
</thead>
<tbody>
  <tr *ngFor="let data of sourceData">
    <td *ngFor="let column of listOfColumns">
      <!-- 传入了自定义模板就用模板,否则默认渲染对应字段的值 -->
      <ng-container *ngIf="column.tdTemplate; else defaultCell">
        <ng-container *ngTemplateOutlet="column.tdTemplate; context: {$implicit: data}"></ng-container>
      </ng-container>
      <ng-template #defaultCell>{{ data[column.columnKey] }}</ng-template>
    </td>
  </tr>
</tbody>

步骤2:父组件传入自定义模板

在使用表格组件的父组件中,先定义各列的单元格模板,再把模板传入列配置即可:

<!-- 父组件模板 -->
<!-- 先定义自定义单元格模板,let-data接收当前行数据 -->
<ng-template #nameCellTpl let-data>
  <a routerLink="/employeeInfo/{{data.Pid}}">
    {{ data.Name }}
  </a>
</ng-template>

<ng-template #pidCellTpl let-data>
  {{ data.Pid }}
</ng-template>

<!-- 引用自定义表格组件 -->
<app-custom-table 
  [listOfColumns]="columnConfig" 
  [sourceData]="tableData"
></app-custom-table>
// 父组件ts
import { ViewChild, TemplateRef, AfterViewInit } from '@angular/core';
import { ColumnItem } from './table.component';

export class ParentComponent implements AfterViewInit {
  // 获取模板引用
  @ViewChild('nameCellTpl') nameCellTpl!: TemplateRef<any>;
  @ViewChild('pidCellTpl') pidCellTpl!: TemplateRef<any>;

  columnConfig: ColumnItem[] = [];
  tableData = []; // 你的表格数据源

  ngAfterViewInit() {
    // 模板初始化完成后再组装列配置
    this.columnConfig = [
      {
        name: 'EmployeeName',
        sortOrder: null,
        sortDirections: ['ascend', 'descend', null],
        columnKey: 'Name',
        tdTemplate: this.nameCellTpl
      },
      {
        name: 'EmployeeId',
        sortOrder: null,
        sortDirections: ['ascend', 'descend', null],
        columnKey: 'pId',
        tdTemplate: this.pidCellTpl
      }
    ];
  }
}

轻量场景替代方案

如果你的自定义单元格只有纯文本内容、不需要用到指令/事件绑定,也可以把tdContent定义为函数类型,直接调用函数获取渲染值:

// ColumnItem定义
export interface ColumnItem {
  // 其他属性不变
  tdContent?: (data: any) => string;
}

// 列配置
listOfColumns: ColumnItem[] = [
  {
    name: 'EmployeeId',
    columnKey: 'pId',
    tdContent: (data) => `ID:${data.Pid}`
  }
]
<!-- 表格模板td部分 -->
<td *ngFor="let column of listOfColumns">
  {{ column.tdContent ? column.tdContent(data) : data[column.columnKey] }}
</td>

不推荐你继续使用innerHTML的方案,除了无法支持Angular模板能力外,还存在XSS安全风险,手动解析插值表达式和指令的成本也非常高。

内容的提问来源于stack exchange,提问作者Ryan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 11:21:02