Infinite Row Model (Enterprise)
The infinite (server-side) row model in apex-grid-enterprise fetches fixed-size blocks of rows from a datasource as the user scrolls, and pushes sort, filter, and quick-filter to the server. Use it for datasets too large to hold in the browser.
Grouped data? This model serves one flat list. If the user explores a hierarchy and only ever opens part of it, the Server-Side Row Model fetches one group level at a time, with server-computed aggregates on the group rows. The two are mutually exclusive.
Setting a datasource
import 'apex-grid-enterprise/define';
const grid = document.createElement('apex-grid-enterprise');
grid.columns = columns;
grid.infiniteRowModel = {
datasource: {
async getRows(params) {
const res = await fetch('/api/rows', {
method: 'POST',
body: JSON.stringify(params),
});
const { rows, total } = await res.json();
return { rows, rowCount: total };
},
},
blockSize: 100,
initialRowCount: 1000,
};
document.body.appendChild(grid);
InfiniteRowModelConfig
| Field | Type | Description |
|---|---|---|
datasource | InfiniteDataSource<T> | Object with a getRows(params) method |
blockSize | number | Rows fetched per block (optional) |
initialRowCount | number | Row count assumed before the first block loads (optional) |
maxRetries | number | Times a rejected getRows is retried. Default 2, at most 10; 0 turns retrying off (0.8) |
retryDelay | number | Milliseconds before the first retry, doubled for each later one. Default 1000 (0.8) |
The getRows contract
getRows receives the current query and returns (or resolves to) the block:
InfiniteGetRowsParams:
| Field | Description |
|---|---|
startRow / endRow | Row index range for the requested block |
sortModel | Active sort expressions (apply server-side) |
filterModel | Active filter expressions (apply server-side) |
quickFilter | Global quick-filter term |
advancedFilterModel | The active advanced filter, or null (0.8). Apply it server-side; while it is set it replaces the column filters, so ignore filterModel then |
InfiniteGetRowsResult:
| Field | Description |
|---|---|
rows | The rows for the requested block |
rowCount | Total count for the current query, if known. Omit for pure "infinite" mode where the total is unknown |
datasource: {
getRows({ startRow, endRow, sortModel, filterModel, quickFilter }) {
return db.query({
offset: startRow,
limit: endRow - startRow,
sort: sortModel,
filter: filterModel,
search: quickFilter,
});
},
}
Server owns ordering
Setting infiniteRowModel disables client-side sort and filter: the server owns ordering. Keep pagination off; the grid virtualizes and lazily loads instead.
Reacting to loads
The apex-rows-loaded event fires after each block resolves:
import { ROWS_LOADED_EVENT } from 'apex-grid-enterprise';
grid.addEventListener(ROWS_LOADED_EVENT, (e) => {
const { rowCount, exact, loadedBlocks, blockSize } = e.detail;
console.log(`${loadedBlocks} block(s) loaded, ~${rowCount} rows`);
});
When a block fails
From 0.8 a rejected getRows is retried up to maxRetries times, retryDelay milliseconds apart and doubling, and each failure fires apex-rows-load-failed with { startRow, endRow, error, retrying }. After the last attempt (retrying: false) the block's rows stay placeholders until refreshRows() or a sort or filter change. Before 0.8 the grid asked again on every scroll over a failed block.
import { ROWS_LOAD_FAILED_EVENT } from 'apex-grid-enterprise';
grid.addEventListener(ROWS_LOAD_FAILED_EVENT, (e) => {
const { startRow, endRow, error, retrying } = e.detail;
if (!retrying) showBanner(`Rows ${startRow} to ${endRow} failed to load`, error);
});
Loading state
Check whether a specific row's block is still loading:
if (grid.isRowLoading(row)) {
// show a skeleton / spinner for this row
}
Forcing a refresh
Discard cached blocks and refetch (for example, after a mutation):
grid.refreshRows();
React example
import { useEffect, useRef } from 'react'
import 'apex-grid-enterprise/define'
export default function InfiniteGrid() {
const ref = useRef<any>(null)
useEffect(() => {
const grid = ref.current
grid.columns = columns
grid.infiniteRowModel = {
datasource: {
async getRows(params: any) {
const res = await fetch('/api/rows', {
method: 'POST',
body: JSON.stringify(params),
})
const { rows, total } = await res.json()
return { rows, rowCount: total }
},
},
blockSize: 100,
}
}, [])
return <apex-grid-enterprise ref={ref} style={{ height: 520 }} />
}