You need to enable JavaScript to run this app. Angular中如何基于列配置动态渲染多类型单元格的nz-table表格
优惠活动
大模型
产品
解决方案
定价
更多

Angular中如何基于列配置动态渲染多类型单元格的nz-table表格

实现逻辑

前置配置调整

现有columnsDefinition缺少「按父项匹配列」的属性,需要先给每个列配置补充适用的父项范围,同时补充日期类的列定义:

columnsDefinition = [ 
  { 
    key: 'value', 
    title: 'Value', 
    type: 'string', 
    isSortable: true, 
    bits: 0,
    applicableParentIds: [1, 2] // 仅当父项id在该数组内时展示该列
  },
  { 
    key: 'description', 
    title: 'Description', 
    type: 'string', 
    isSortable: false, 
    bits: 0,
    applicableParentIds: [1]
  },
  { 
    key: 'flags', 
    title: 'Active', 
    type: 'boolean', 
    isSortable: false, 
    bits: 0,
    applicableParentIds: [1, 2]
  },
  { 
    key: 'flags', 
    title: 'Only user', 
    type: 'boolean', 
    isSortable: true, 
    bits: 1,
    applicableParentIds: [2]
  },
  { 
    key: 'dateBegin', 
    title: 'Start Date', 
    type: 'date', 
    isSortable: true, 
    bits: 0,
    applicableParentIds: [2]
  }
]

组件内维护当前表格对应的父项id,可从路由参数、接口返回值中获取:

currentParentId: number;

组件核心辅助方法

1. 按父项动态过滤当前可见列

通过计算属性自动返回当前父项下需要展示的列集合,保证表头和表体的列配置完全同步:

get currentVisibleColumns() {
  return this.columnsDefinition.filter(col => 
    col.applicableParentIds.includes(this.currentParentId)
  );
}

2. flags指定位值提取

从整型flags字段中读取指定位的布尔值,匹配业务规则:

getFlagBitValue(flags: number, bit: number): boolean {
  if (bit < 0) return false;
  return (flags & (1 << bit)) !== 0;
}

3. flags指定位值写入

修改布尔类型单元格时,同步把变更值写回flags字段的对应位,不影响其他位的原有值:

setFlagBitValue(row: any, bit: number, value: boolean): void {
  if (bit < 0) return;
  row.flags = value 
    ? row.flags | (1 << bit) 
    : row.flags & ~(1 << bit);
  // 如需触发接口更新、全局状态同步,可在此处补充对应逻辑
}

4. 列排序处理

兼容普通字段、flags位字段的排序逻辑,和列定义的isSortable配置联动:

onSortChange(col: any, sortOrder: 'ascend' | 'descend' | null) {
  const sortedData = [...this.resultsTable.data];
  sortedData.sort((a, b) => {
    let aVal, bVal;
    // 针对flags类型的列,按指定位的值排序
    if (col.key === 'flags') {
      aVal = this.getFlagBitValue(a.flags, col.bits);
      bVal = this.getFlagBitValue(b.flags, col.bits);
    } else {
      aVal = a[col.key];
      bVal = b[col.key];
    }
    if (sortOrder === 'ascend') return aVal > bVal ? 1 : -1;
    if (sortOrder === 'descend') return aVal < bVal ? 1 : -1;
    return 0;
  });
  this.resultsTable.data = sortedData;
}

模板调整

表头部分

替换原固定列遍历为动态可见列遍历,同时绑定排序逻辑:

<thead>
  <tr>
    <th *ngFor="let col of currentVisibleColumns"
        [nzSortOrder]="col.isSortable ? 'descend' : null"
        (nzSortOrderChange)="onSortChange(col, $event)">
      {{col.title}}
    </th>
  </tr>
</thead>

表体单元格部分

每一行的单元格逐列遍历,通过*ngSwitch根据列类型匹配对应的渲染组件:

<tbody>
  <ng-container *ngFor="let row of resultsTable.data">
    <tr>
      <td *ngFor="let col of currentVisibleColumns">
        <ng-container [ngSwitch]="col.type">
          <!-- 字符串类型:直接展示文本 -->
          <span *ngSwitchCase="'string'">{{row[col.key]}}</span>
          <!-- 布尔类型:渲染nz-checkbox,绑定flags位的读写逻辑 -->
          <nz-checkbox *ngSwitchCase="'boolean'"
            [ngModel]="getFlagBitValue(row.flags, col.bits)"
            (ngModelChange)="setFlagBitValue(row, col.bits, $event)">
          </nz-checkbox>
          <!-- 日期类型:渲染nz-date-picker,双向绑定原日期字段 -->
          <nz-date-picker *ngSwitchCase="'date'"
            [(ngModel)]="row[col.key]"
            [nzShowTime]="true">
          </nz-date-picker>
          <!-- 兜底默认渲染 -->
          <span *ngSwitchDefault>{{row[col.key]}}</span>
        </ng-container>
      </td>
    </tr>
  </ng-container>
</tbody>

扩展说明

  • 后续新增列类型(如数字输入、下拉选择等),只需在*ngSwitch中新增对应case分支即可,无需改动整体结构
  • 列配置完全可抽离为外部配置文件,实现多场景表格的复用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 19:36:03