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

ag-grid-angular分组模式下仅按子行分页的实现方案求助

AG-Grid分组模式下仅按子行数量分页的解决方案

核心思路

由于AG-Grid原生分页逻辑无法排除分组行单独统计子行,最可靠的方案是绕过原生分页,自行控制数据源的分页切片,再重构分组结构传给表格,确保分页仅基于子行数量计算。

具体实现步骤

1. 数据预处理与分页参数维护

先保留所有原始子行数据,自己维护分页核心参数(每页条数、当前页码、总子行数),避免依赖AG-Grid原生分页状态。

// 假设原始子行数据结构
interface ChildItem {
  groupKey: string; // 分组字段
  id: number;
  name: string;
  // 其他业务字段
}

// 组件内变量
originalChildData: ChildItem[] = []; // 所有子行原始数据
gridDataSource: any[] = []; // 传给AG-Grid的带分组结构的数据
pageSize = 10;
currentPage = 1;
totalChildCount = 0;
gridApi: GridApi | undefined;

2. 分页数据构建与表格刷新

根据当前分页参数截取子行,再将这些子行重新按分组字段构建成AG-Grid需要的「分组行+子行」结构,最后刷新表格。

ngOnInit() {
  // 初始化时统计总子行数
  this.totalChildCount = this.originalChildData.length;
  this.refreshGridData();
}

// 根据分页参数生成表格数据源
refreshGridData() {
  // 计算当前页子行的截取范围
  const startIdx = (this.currentPage - 1) * this.pageSize;
  const endIdx = startIdx + this.pageSize;
  const currentPageChildren = this.originalChildData.slice(startIdx, endIdx);

  // 按分组字段整理子行
  const groupMap = new Map<string, ChildItem[]>();
  currentPageChildren.forEach(item => {
    const key = item.groupKey;
    if (!groupMap.has(key)) groupMap.set(key, []);
    groupMap.get(key)!.push(item);
  });

  // 构建AG-Grid所需的分组数据格式
  this.gridDataSource = [];
  groupMap.forEach((children, key) => {
    // 添加分组行(标记group: true)
    this.gridDataSource.push({
      groupKey: key,
      group: true,
      // 可自定义分组行显示字段
    });
    // 添加当前分组下的子行
    this.gridDataSource.push(...children);
  });

  // 刷新表格数据
  this.gridApi?.setRowData(this.gridDataSource);
}

3. 表格配置与自定义分页控件

关闭AG-Grid原生分页,使用自定义分页控件切换页码,触发数据刷新。

<!-- AG-Grid配置 -->
<ag-grid-angular
  [rowData]="gridDataSource"
  [columnDefs]="columnDefs"
  [groupDefaultExpanded]="1" <!-- 默认展开分组 -->
  [pagination]="false" <!-- 禁用原生分页 -->
  (gridReady)="onGridReady($event)"
></ag-grid-angular>

<!-- 自定义分页控件 -->
<div class="pagination-bar">
  <button (click)="goPrevPage()" [disabled]="currentPage === 1">上一页</button>
  <span>第 {{currentPage}} 页 / 共 {{Math.ceil(totalChildCount / pageSize)}} 页</span>
  <button (click)="goNextPage()" [disabled]="currentPage >= Math.ceil(totalChildCount / pageSize)">下一页</button>
</div>
// 分页切换方法
goPrevPage() {
  if (this.currentPage > 1) {
    this.currentPage--;
    this.refreshGridData();
  }
}

goNextPage() {
  const totalPages = Math.ceil(this.totalChildCount / this.pageSize);
  if (this.currentPage < totalPages) {
    this.currentPage++;
    this.refreshGridData();
  }
}

onGridReady(params: GridReadyEvent) {
  this.gridApi = params.api;
}

原方案问题说明

你之前尝试的「修改pageSize加上分组行数」方案不可行的原因:

  • 分组行数量会随用户展开/折叠操作动态变化,固定计算的分组行数不准确;
  • paginationSetPageSize会修改AG-Grid内部分页状态,导致自定义维护的pageSize与表格内部状态不一致,引发数据展示混乱。

扩展支持(可选)

如果需要排序、筛选功能,只需先对originalChildData执行排序/筛选操作,再重新计算totalChildCount并调用refreshGridData()即可,分页逻辑不受影响。

内容的提问来源于stack exchange,提问作者怕疼的猫

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 07:35:21