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
相关产品推荐
相关产品推荐

