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
相关产品推荐
相关产品推荐

