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.
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) |
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 |
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`);
});
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 }} />
}