EntityPagination<O extends Object> class
A lazily loaded, paginated view over a select operation.
It keeps the pages it has already loaded and never fetches implicitly:
the synchronous accessors (operator [], loadedEntities) only ever see
what is loaded, and only the FutureOr methods (getAt, getPage,
loadNextPage, loadAll, stream) fetch.
Pages are 1-based (matching the page parameter of the select*
methods) and entry indexes are 0-based (matching a Dart List):
see indexOfPage and pageOfIndex.
Pages can be loaded out of order, leaving gaps: getAt(45) with a limit
of 20 loads only page 3, so loadedPages is [3] while indexes 0..39
stay unloaded.
The total length is not known upfront
A paginated select doesn't count the matching entries, so totalLength is
null until the final page is identified. Since every page except the last
one holds exactly limit entries, identifying the final page is enough to
compute the total — even when there are gaps:
totalLength == (finalPage - 1) * limit + <entries of finalPage>
See isFinalPageResolved for when that happens.
Not a List
This is deliberately not a List or an Iterable: both require a length,
which is exactly what a paginated select can't answer until it reaches the
end. Use operator [] for what is loaded, and loadAll when a full list is
really needed.
Consistency
Each page is an independent select, without a shared Transaction. Entries
inserted or deleted between two page loads shift the offsets, so a page
loaded later can repeat or skip entries. This is inherent to offset-based
pagination; ordering by ID (the default of the paginate* methods) makes it
as stable as it can be.
Constructors
-
EntityPagination({required int limit, required EntityPageLoader<
O> pageLoader, String? query, EntityPaginationListener<O> ? onEvent})
Properties
- finalPage → int?
-
The final page, or
nullwhile unresolved. See isFinalPageResolved.no setter - hashCode → int
-
The hash code for this object.
no setterinherited
- isFinalPageResolved → bool
-
Whether the final page has been identified.
no setter
- isKnownEmpty → bool
-
Whether the select is known to match no entry at all.
no setter
- limit → int
-
The page size: the maximum number of entries of a page.
final
-
loadedEntities
→ List<
O> -
The loaded entries, in index order. Gaps are skipped.
no setter
- loadedEntitiesLength → int
-
The number of loaded entries. Entries in a gap are not counted, so this
can be less than
maxLoadedIndex + 1.no setter -
loadedPages
→ List<
int> -
The loaded page numbers, ascending. Can have gaps.
no setter
- loadedPagesLength → int
-
The number of loaded pages.
no setter
- maxKnownPage → int?
-
The highest page known to exist: the highest loaded page that came back
with entries.
nullif no page with entries was loaded yet.no setter - maxLoadedIndex → int?
-
The highest entry index that is loaded, or
nullif none is.no setter - maxLoadedPage → int?
-
The highest loaded page, or
nullif nothing was loaded yet.no setter -
onEvent
↔ EntityPaginationListener<
O> ? -
An optional hook notified of what is being fetched, or
null(the default) to notify nothing. See EntityPaginationEvent.getter/setter pair -
pageLoader
→ EntityPageLoader<
O> -
Loads a page. See EntityPageLoader.
final
- query → String?
-
An optional description of the paginated query, for toString.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- totalLength → int?
-
The total number of entries, or
nullwhile isFinalPageResolved isfalse.no setter
Methods
-
getAt(
int index) → FutureOr< O?> -
The entry at
index, loading its page if needed. Returnsnullifindexis out of range. -
getPage(
int page) → FutureOr< List< O> > -
The entries of
page, loading it if needed. -
getRange(
int startIndex, int endIndex) → FutureOr< List< O> > -
The entries from
startIndex(inclusive) toendIndex(exclusive), loading every page spanning the range, including pages inside a gap. -
indexOfPage(
int page) → int -
The index of the 1st entry of
page. -
information(
{bool extended = false}) → Map< String, dynamic> -
isIndexKnownOutOfRange(
int index) → bool -
Whether
indexis known to be out of range. -
isIndexLoaded(
int index) → bool -
Returns
trueif the entry atindexis loaded. -
isPageLoaded(
int page) → bool -
Returns
trueifpagewas already loaded (even if it came back empty). -
loadAll(
{int? maxPages}) → FutureOr< int?> - Loads every page from page 1 until the end, so that afterwards loadedEntities holds the complete result with no gap.
-
loadedPageEntities(
int page) → List< O> ? -
The loaded entries of
page, ornullif it is not loaded. -
loadNextPage(
) → FutureOr< List< O> ?> - Loads the page after maxLoadedPage (or page 1 when nothing is loaded).
-
loadPage(
int page) → FutureOr< List< O> > -
Loads
page(1-based), or returns it if already loaded. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
pageOfIndex(
int index) → int -
The page holding the entry at
index. -
refresh(
) → FutureOr< void> - Re-fetches the currently loaded pages, discarding what was known about the end (it may have moved).
-
reset(
) → void - Discards every loaded page and everything known about the end, keeping the query.
-
stream(
{int fromPage = 1}) → Stream< O> -
Streams the entries from
fromPage, loading the pages as it goes. -
toString(
) → String -
A string representation of this object.
override
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
-
operator [](
int index) → O? -
The loaded entry at
index, ornullif it is not loaded (in a gap, in a page not loaded yet, or out of range).