AG Grid无限行模型中自定义Refresh/Cancel功能实现咨询
AG Grid Infinite Row Model 实现仅取消刷新请求的方案
AG Grid 本身没有直接提供区分「刷新触发请求」和「分页触发请求」的官方配置,但可以通过请求标识+取消令牌隔离的方式实现你的需求,不需要大量自定义逻辑,下面是具体实现思路和最佳实践:
核心实现思路
1. 给请求打标识区分来源
在 AG Grid 的 getRows 回调(或你的API请求层)中,给每个请求添加类型标识,明确区分请求来源:
- 分页请求:由AG Grid滚动/点击分页按钮触发,标记为
type: 'pagination' - 刷新请求:由自定义Refresh按钮触发,标记为
type: 'refresh'
2. 隔离取消令牌
维护一个独立的 AbortController 实例专门用于刷新请求,分页请求使用AG Grid默认的取消机制(或单独的控制器),两者互不干扰:
- 每次点击Refresh按钮时,先销毁旧的刷新控制器(如果存在),创建新的控制器,避免旧请求残留
- Cancel按钮仅调用刷新控制器的
abort()方法,不会影响分页请求
3. 结合AG Grid API实现刷新逻辑
手动刷新时,需要清空AG Grid的无限缓存并重新加载第一页,可通过以下API实现:
// 清空无限缓存并触发重新加载 gridApi.refreshInfiniteCache(true); // 或者直接重置数据源(如果需要完全重置) gridApi.setDatasource(yourDatasource);
具体代码示例
1. 维护取消令牌和请求状态
// 全局维护刷新请求的取消控制器 let refreshAbortController = null; // 自定义Refresh按钮点击事件 const handleRefresh = () => { // 先取消之前的刷新请求 if (refreshAbortController) { refreshAbortController.abort('用户取消刷新'); } // 创建新的控制器 refreshAbortController = new AbortController(); // 清空AG Grid缓存并触发刷新(标记本次请求为refresh类型) gridApi.refreshInfiniteCache(true); }; // 自定义Cancel按钮点击事件 const handleCancel = () => { if (refreshAbortController) { refreshAbortController.abort('用户取消刷新'); refreshAbortController = null; // 重置控制器 } };
2. 在getRows中区分请求并应用令牌
const datasource = { getRows: (params) => { // 判断请求类型:如果是从第一页开始加载,且不是分页触发,标记为刷新请求 const isRefresh = params.startRow === 0 && !params.context?.isPagination; const signal = isRefresh ? refreshAbortController?.signal : undefined; // 调用API,传入对应的信号 fetchRickAndMortyData(params.startRow, params.endRow, signal) .then(data => { params.successCallback(data.rows, data.totalRows); }) .catch(err => { // 忽略刷新请求的取消错误 if (err.name !== 'AbortError' || !isRefresh) { params.failCallback(); } }); } };
3. React Query 集成优化
如果使用React Query,可以给刷新请求和分页请求设置不同的queryKey,取消时仅针对刷新的query:
// 分页请求的queryKey const paginationQueryKey = ['rickAndMorty', page]; // 刷新请求的queryKey(单独标识) const refreshQueryKey = ['rickAndMorty', 'refresh']; // 刷新时,取消旧的刷新请求并重新获取 const handleRefresh = () => { queryClient.cancelQueries({ queryKey: refreshQueryKey }); queryClient.invalidateQueries({ queryKey: refreshQueryKey }); }; // Cancel按钮仅取消刷新请求 const handleCancel = () => { queryClient.cancelQueries({ queryKey: refreshQueryKey }); };
最佳实践
- 避免内存泄漏:每次刷新前取消旧请求并销毁控制器,Cancel后重置控制器实例
- 清晰的状态标记:在AG Grid的
context或请求参数中明确标记请求类型,避免误判 - 兼容AG Grid默认行为:分页请求保留AG Grid原生的取消逻辑,不要干扰其正常分页流程
- 错误处理:区分取消错误和其他API错误,避免不必要的
failCallback触发
内容的提问来源于stack exchange,提问作者Supernectar
相关产品推荐
相关产品推荐

