Angular2中AG Grid的valueGetter如何与滚动分页(setDatasource)配合使用?
嘿,你的valueGetter写法没问题,要配合无限滚动分页(也就是AG Grid的无限行模型)其实很简单,核心是实现AG Grid的IDatasource接口,把你的数据分页逻辑塞进去,而且这和你现有的valueGetter完全兼容——因为valueGetter只关心行数据本身,不管数据是一次性加载还是分页加载的。
下面一步步来实现:
1. 配置Grid为无限行模型模式
首先要在你的gridOptions里开启无限滚动的基础配置:
this.gridOptions = { rowModelType: 'infinite', // 必须设置成这个,开启无限滚动 pagination: false, // 无限滚动不需要普通的分页组件 cacheBlockSize: 100, // 每次滚动加载的行数,根据你的需求调整 maxBlocksInCache: 5, // 缓存的最大数据块数,防止内存占用过高 // 保留你原来的其他配置,比如columnDefs之类的 };
2. 实现分页数据源(IDatasource)
你需要创建一个符合IDatasource接口的对象,它的核心是getRows方法——AG Grid会在滚动到需要新数据的时候自动调用这个方法,请求对应范围的行数据。
如果你的数据是本地的(就像你现在的gridData.rows),可以这样写:
import { IDatasource, IGetRowsParams } from 'ag-grid-community'; // 定义你的分页数据源 private gridDatasource: IDatasource = { getRows: (params: IGetRowsParams) => { // AG Grid会告诉你需要从哪一行(startRow)加载到哪一行(endRow) const startIndex = params.startRow; const endIndex = params.endRow; // 从你的本地数据中截取对应范围的行 const pageData = this.gridData.rows.slice(startIndex, endIndex); // 告诉AG Grid数据加载完成,第二个参数是总数据量(用来计算滚动条长度) params.successCallback(pageData, this.gridData.rows.length); } };
如果之后要改成后端分页,只需要把slice的逻辑换成调用后端接口,传递startIndex和endIndex(或者转换成页码+每页条数),然后把后端返回的数据和总条数传给successCallback就行。
3. 绑定数据源到Grid
要等Grid初始化完成后再设置数据源,所以最好放在ngAfterViewInit钩子函数里:
import { AfterViewInit } from '@angular/core'; // 让你的组件实现AfterViewInit export class YourGridComponent implements AfterViewInit { // ... 你的其他代码 ngAfterViewInit() { // 确保Grid的api已经初始化完成 if (this.gridOptions.api) { this.gridOptions.api.setDatasource(this.gridDatasource); } } }
4. 保留你的valueGetter逻辑
你的columnDefs写法完全不需要修改!因为当AG Grid通过数据源加载每页数据后,行数据还是原来的数组格式,valueGetter: scopeOutCurrIndex(i)依然能正确拿到params.data[i]对应的值。
举个例子,假设当前加载的行是["data1","data2"],valueGetter依然会返回对应索引的元素,和之前一次性加载所有数据的行为完全一致。
额外提示
- 如果需要刷新数据(比如数据更新了),可以调用
this.gridOptions.api.refreshInfiniteCache(),AG Grid会重新加载数据。 - 如果你的数据量很大,
cacheBlockSize不要设置得太大,避免一次性加载过多数据导致卡顿。
内容的提问来源于stack exchange,提问作者Shyam Devasia

