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

Angular Mat-Table动态生成列并横向展示嵌套JSON数据求助

解决方案

问题根因

  • 原实现错误在单个<td>内嵌套多个<td>,违反HTML表格结构规范,浏览器自动修正DOM结构导致内容丢失
  • 动态列生成逻辑错误:每组条件对应3个独立列,原逻辑仅生成1个列承载3个字段,不符合MatTable的列渲染规则
  • 表头未做语义化处理,显示内容无法识别

修复后组件TS代码

import { Component, OnInit } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';

export class SamplePocComponent implements OnInit {
  lstRulesCheck: MatTableDataSource<any>;
  displayedColumns: string[] = ['SAMPLERULENAME'];
  payload: any[] = [
    {"SAMPLERULEID": 69,"SAMPLERULENAME": "Sample1","SAMPLERULECONDITIONS": [{"SAMPLERULECONDITIONID": 148,"SAMPLERULEID": 69,"SAMPLERULENAME": "Sample1","CONDITIONFIELDID": 1,"DISPLAYNAME": "Country","OPERATOR": "=","COUNT": 10},{"SAMPLERULECONDITIONID": 149,"SAMPLERULEID": 69,"SAMPLERULENAME": "Sample1","CONDITIONFIELDID": 2,"DISPLAYNAME": "State","OPERATOR": "=","COUNT": 11},{"SAMPLERULECONDITIONID": 150,"SAMPLERULEID": 69,"SAMPLERULENAME": "Sample1","CONDITIONFIELDID": 3,"DISPLAYNAME": "City","OPERATOR": "="},{"SAMPLERULECONDITIONID": 151,"SAMPLERULEID": 69,"SAMPLERULENAME": "Sample1","CONDITIONFIELDID": 4,"DISPLAYNAME": "Town","OPERATOR": "IS NULL"}]},{"SAMPLERULEID": 80,"SAMPLERULENAME": "Sample123","SAMPLERULECONDITIONS": [{"SAMPLERULECONDITIONID": 208,"SAMPLERULEID": 80,"SAMPLERULENAME": "Sample123","CONDITIONFIELDID": 92,"DISPLAYNAME": "Date","OPERATOR": "IS NOT NULL","COUNT": 12}]},{"SAMPLERULEID": 74,"SAMPLERULENAME": "Sample2","SAMPLERULECONDITIONS": [{"SAMPLERULECONDITIONID": 153,"SAMPLERULEID": 74,"SAMPLERULENAME": "Sample2","CONDITIONFIELDID": 89,"DISPLAYNAME": "Primary","OPERATOR": "IS NOT NULL","COUNT": 5},{"SAMPLERULECONDITIONID": 156,"SAMPLERULEID": 74,"SAMPLERULENAME": "Sample2","CONDITIONFIELDID": 90,"DISPLAYNAME": "Secondary","OPERATOR": ">","COUNT": 9},{"SAMPLERULECONDITIONID": 157,"SAMPLERULEID": 74,"SAMPLERULENAME": "Sample2","CONDITIONFIELDID": 89,"DISPLAYNAME": "Third","OPERATOR": "IS NULL","COUNT": 99}]}
  ];
  maxConditionCount: number = 0;

  constructor() {}

  ngOnInit() {
    this.getSampleRules();
  }

  getSampleRules() {
    // 计算最大条件数
    this.payload.forEach(element => {
      const conditionLen = element.SAMPLERULECONDITIONS?.length || 0;
      if (conditionLen > this.maxConditionCount) {
        this.maxConditionCount = conditionLen;
      }
    });

    // 生成动态列:每个条件对应3列:字段名/操作符/数量
    for (let i = 1; i <= this.maxConditionCount; i++) {
      this.displayedColumns.push(`condition${i}_name`);
      this.displayedColumns.push(`condition${i}_operator`);
      this.displayedColumns.push(`condition${i}_count`);
    }

    this.lstRulesCheck = new MatTableDataSource(this.payload);
  }

  // 获取单元格值
  getCellValue(col: string, element: any): any {
    if (col === 'SAMPLERULENAME') return element.SAMPLERULENAME;
    // 拆分列名:condition1_name 拆出索引0,属性name
    const [conditionPrefix, field] = col.split('_');
    const conditionIndex = parseInt(conditionPrefix.replace('condition', '')) - 1;
    const condition = element.SAMPLERULECONDITIONS?.[conditionIndex];
    if (!condition) return '';
    // 映射字段
    const fieldMap = {
      name: 'DISPLAYNAME',
      operator: 'OPERATOR',
      count: 'COUNT'
    };
    return condition[fieldMap[field]] ?? '';
  }

  // 获取表头显示名称
  getHeaderText(col: string): string {
    if (col === 'SAMPLERULENAME') return '规则名称';
    const [conditionPrefix, field] = col.split('_');
    const conditionNum = conditionPrefix.replace('condition', '');
    const fieldTextMap = {
      name: '字段',
      operator: '操作符',
      count: '数量'
    };
    return `条件${conditionNum}${fieldTextMap[field]}`;
  }
}

修复后模板代码

<table mat-table [dataSource]="lstRulesCheck" class="mat-elevation-z8 w-full">
  <ng-container *ngFor="let col of displayedColumns" [matColumnDef]="col">
    <th mat-header-cell *matHeaderCellDef> {{getHeaderText(col)}} </th>
    <td mat-cell *matCellDef="let element" style="word-break: break-all; padding: 8px 16px;"> 
      {{getCellValue(col, element)}}
    </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

实现效果

  • 自动按所有规则的最大条件数生成对应列,无多余空列
  • 条件数不足的规则对应单元格自动留空
  • 所有字段正常渲染,结构符合MatTable规范
  • 表头语义化显示,用户可直接识别列含义

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 16:15:05