
本文介绍如何将嵌套数组中的每个对象以“字段名-字段值”垂直两行方式渲染为表格,避免传统行列式布局,实现更清晰的字段展示结构。
本文介绍如何将嵌套数组中的每个对象以“字段名-字段值”垂直两行方式渲染为表格,避免传统行列式布局,实现更清晰的字段展示结构。
在 Angular 应用中,当 history 是一个对象数组(如 ChangeLogEntryDto[]),而你希望为每个对象单独渲染一张紧凑型键值表(即每列仅含一个字段名 + 对应值,而非传统横向多列布局),关键在于放弃 mat-table 的标准数据源驱动模式,改用手动遍历字段名的方式动态生成行。
原代码中使用 <table mat-table [dataSource]="[entry]"> 并配合 *matRowDef,本质是将单个对象当作「一行」渲染——这导致所有字段水平铺开,不符合“字段名与值分两行垂直对齐”的需求。正确做法是:对每个 entry,遍历 displayedColumns 数组,为每个字段名生成独立的一行(<tr>),其中 <th> 显示字段名(key),<td> 显示对应值(entry[key])。
以下是优化后的模板代码:
<div *ngFor="let entry of history">
<table mat-table class="key-value-table">
<tr *ngFor="let key of displayedColumns">
<th mat-header-cell>{{ key | titlecase }}</th>
<td mat-cell>{{ entry[key] || '-' }}</td>
</tr>
</table>
</div>✅ 优势说明:
- 每个 entry 渲染一张独立小表,结构清晰、语义明确;
- *ngFor="let key of displayedColumns" 确保字段顺序可控且可复用列配置;
- 使用 | titlecase 管道提升可读性(如 registrarSurname → Registrar Surname);
- {{ entry[key] || '-' }} 提供空值兜底,避免空白单元格。
⚠️ 注意事项:
- mat-table 在此场景下仅作为样式容器,无需绑定 dataSource,也不需 matColumnDef 或 matHeaderRowDef —— 这些是为复杂数据表设计的,此处反而增加冗余;
- 若字段值含日期、布尔值等需格式化,建议封装为管道(如 date:'medium'、yesNo);
- 如需响应式或打印友好,可添加 CSS 类控制表格宽度与字体大小;
- 若字段数量较多,考虑添加 max-height 与 overflow-y: auto 防止页面过长。
该方案轻量、可维护性强,完美匹配“字段名在上、值在下”的垂直展示诉求,同时保持与现有 displayedColumns 配置的无缝集成。

















