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

ag-grid中serverSideDataSource会话存筛选后刷新窗口触发两次问题

AG Grid 刷新页面恢复Session筛选条件时,serverSideDataSource.getRows 触发两次的问题

问题描述

在AG Grid中,将筛选条件存储在Session中,刷新窗口后,serverSideDataSource方法内的getRows会被触发两次。

复现代码

serverSideDataSource(count: number) {
    return {
      getRows: (params) => {
        // 为动态创建的列处理排序模型
        params.request.sortModel.forEach((sortItem) => {
          if (sortItem.colId.split('&').length > 1) {
            const sortModelObj = {};
            sortItem.colId.split('&').forEach((subCol) => (sortModelObj[subCol] = { ...sortItem, colId: subCol }));
            params.request.sortModel = Object.values(sortModelObj);
          }
        });
        const sortModel = Object.keys(params.request.sortModel);
        let where = this.whereBy;
        if (this.filterStateWhere.length !== 0) {
          where = [...this.whereBy, ...this.filterStateWhere];
          const mainFilterModel = this.gridApi.getFilterModel();
          const filterStateModel = JSON.parse(this.cacheSvc.getState('session', `${this.viewType}/${'FilterState'}`));
          params.request.filterModel = { ...mainFilterModel, ...filterStateModel };
        }
        const filterModel = Object.keys(params.request.filterModel) as string[];
        this.payload = getDefaultPayload({
          params,
          gridOptions: this.gridOptions,
          order: this.orderBy,
          where,
          select: this.selectBy
        });
        this.payload.limit = this.gridOptions.paginationPageSize;
        // 主服务请求
        if (filterModel.length !== 0) {
          this.filterChecks(params, filterModel, sortModel);
        } else {
          if (sortModel.length !== 0) {
            this.payload.offset = this.gridApi.paginationGetCurrentPage() > 0 ? params.request.startRow : 0;
            this.payload = this.applySortPayload(params.request.sortModel);
          }
          this.togglePagination(count);
          this.fetchItemsRequest(params, count);
        }
      }
    };
  }

原因分析与解决方案

1. 初始化与筛选恢复的时序冲突

刷新页面时,AG Grid会先完成基础初始化并触发一次getRows,之后你从Session中恢复筛选条件并更新filterModel,Grid检测到筛选条件变化会再次触发请求,导致两次调用。

解决方式:
在Grid初始化前就将Session中的筛选条件注入到gridOptions的defaultFilterModel中,让Grid带着筛选条件完成初始化,避免后续二次触发请求。

2. 直接修改params.request触发变更检测

代码中直接修改了params.request.filterModel:

params.request.filterModel = { ...mainFilterModel, ...filterStateModel };

AG Grid内部会监听请求参数的变化,这种直接修改会触发额外的请求。

解决方式:
跳过修改Grid的请求参数,在构建payload时直接合并筛选条件:

// 移除直接修改params.request.filterModel的代码
const combinedFilterModel = { ...mainFilterModel, ...filterStateModel };
// 在构建payload时传入合并后的筛选条件
this.payload = getDefaultPayload({
  params,
  gridOptions: this.gridOptions,
  order: this.orderBy,
  where,
  select: this.selectBy,
  filterModel: combinedFilterModel // 需确保getDefaultPayload支持该参数
});

3. 分页操作触发二次请求

代码中调用的this.togglePagination(count)如果内部修改了分页配置(比如切换分页开关、修改每页条数),会导致Grid重新发起请求。

解决方式:
确保分页配置在Grid初始化时就设置完成,避免在getRows中修改分页参数。如果必须调整,先判断当前分页状态是否符合预期,避免重复触发。

额外优化建议

  • 给请求方法加防抖:在fetchItemsRequest或filterChecks中加入防抖逻辑,短时间内重复触发的请求只执行最后一次。
  • 日志排查:在getRows开头添加console.log('getRows触发', params.request),对比两次请求的参数差异,明确触发根源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 10:53:13