Angular中合并相同内容单元格的实现方法咨询
Angular表格动态合并重复单元格(API数据场景)
要实现不同列按各自重复数量合并单元格,核心思路是先预处理API返回的数据,标记每个列的重复组信息,再在模板中根据标记动态设置rowspan并控制单元格显示。以下是具体实现步骤:
1. 组件内预处理数据
先对API获取的overviewStcs数据进行处理,为每个数据项添加对应列的「是否为组内第一个项」和「组长度(即rowspan值)」属性。以taskName和description列为例:
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-task-table', templateUrl: './task-table.component.html', styleUrls: ['./task-table.component.css'] }) export class TaskTableComponent implements OnInit { overviewStcs: any[] = []; // API返回的原始数据 processedData: any[] = []; // 预处理后的数据 ngOnInit(): void { // 假设这里已经从API获取到overviewStcs数据 this.fetchDataFromApi().then(() => { // 先按要合并的列排序(确保重复项连续,否则合并会错乱) this.overviewStcs.sort((a, b) => a.taskName.localeCompare(b.taskName)); // 预处理数据 this.processedData = this.generateRowspanData(this.overviewStcs); }); } // 模拟API请求(替换为实际接口调用) async fetchDataFromApi() { this.overviewStcs = [ { taskName: '模拟器监控', description: '设备状态监控', deadline: new Date('2024-05-01') }, { taskName: '模拟器监控', description: '设备状态监控', deadline: new Date('2024-05-02') }, { taskName: '模拟器监控', description: '设备状态监控', deadline: new Date('2024-05-03') }, { taskName: '模拟器监控', description: '设备状态监控', deadline: new Date('2024-05-04') }, { taskName: '模拟器监控', description: '设备状态监控', deadline: new Date('2024-05-05') }, { taskName: '模拟器监控', description: '设备状态监控', deadline: new Date('2024-05-06') }, { taskName: '数据同步', description: '云端数据同步', deadline: new Date('2024-05-07') }, { taskName: '数据同步', description: '云端数据同步', deadline: new Date('2024-05-08') }, { taskName: '日志分析', description: '系统日志排查', deadline: new Date('2024-05-09') } ]; } // 生成带rowspan标记的数据 generateRowspanData(rawData: any[]) { // 统计每个列的重复次数 const taskNameCountMap = new Map<string, number>(); const descriptionCountMap = new Map<string, number>(); rawData.forEach(item => { taskNameCountMap.set(item.taskName, (taskNameCountMap.get(item.taskName) || 0) + 1); descriptionCountMap.set(item.description, (descriptionCountMap.get(item.description) || 0) + 1); }); // 遍历数据,标记每个项的显示状态和rowspan值 let lastTaskName = ''; let lastDescription = ''; return rawData.map(item => { // 处理taskName列 const isFirstTaskName = item.taskName !== lastTaskName; const taskNameRowspan = isFirstTaskName ? taskNameCountMap.get(item.taskName) : 0; lastTaskName = isFirstTaskName ? item.taskName : lastTaskName; // 处理description列 const isFirstDescription = item.description !== lastDescription; const descriptionRowspan = isFirstDescription ? descriptionCountMap.get(item.description) : 0; lastDescription = isFirstDescription ? item.description : lastDescription; return { ...item, isFirstTaskName, taskNameRowspan, isFirstDescription, descriptionRowspan }; }); } }
2. 模板中渲染合并后的表格
在模板里根据预处理的标记,控制单元格的显示和rowspan属性:
<table border="1"> <thead> <tr> <th>项目名称</th> <th>描述</th> <th>截止日期</th> </tr> </thead> <tbody> <tr *ngFor="let item of processedData"> <!-- 项目名称列:仅显示组内第一个项,设置rowspan --> <td *ngIf="item.isFirstTaskName" [attr.rowspan]="item.taskNameRowspan"> {{ item.taskName }} </td> <!-- 描述列:同理处理 --> <td *ngIf="item.isFirstDescription" [attr.rowspan]="item.descriptionRowspan"> {{ item.description }} </td> <!-- 截止日期列:无需合并,正常显示 --> <td>{{ item.deadline | date: 'dd-MM-yyyy' }}</td> </tr> </tbody> </table>
关键注意事项
- 数据排序:必须确保要合并的列的重复项是连续的,否则合并后的单元格会错位。预处理前一定要对数据按对应列排序(比如示例中的
taskName排序)。 - 多列独立合并:如果不同列的重复组完全独立(比如
taskName合并5个,description合并3个),上述逻辑依然适用,因为每个列的标记是单独计算的。 - 动态数据更新:如果API数据会动态刷新,只需在数据更新后重新调用
generateRowspanData方法更新processedData即可。
内容的提问来源于stack exchange,提问作者emreertunc
相关产品推荐
相关产品推荐

