CARVIEW |
Navigation Menu
-
Notifications
You must be signed in to change notification settings - Fork 12
Data Providers #4
Description
Overview
As part of dgrid development, we've identified data providers - objects that can be instructed of state changes and notify observers as a result - as being a useful reactive pattern to drive grid interaction.
We should identify what we expect to encounter to ensure there are no interactions that could become problematic as the grid continues to expand in functionality:
- An interface with the methods to call on the data provider to notify it of state changes
- A state object that tracks the grid's initial configuration plus any state changes
- What, if any, state changes should result in other states being changed
- Information that clarifies the capabilities and state of the returned items within the larger data set
- Information that clarifies the capabilities and state of each item within the returned data
Data Provider Internal State
This data is available to all data provider implementations.
size: { dataLength: number; totalLength: number; }
sort: { columnId: string; direction: 'asc' | 'desc' }[]
slice: { start: number; count: number; }
limit: { start: number; count: number; }
expanded: { [ itemId: string ]: boolean }
selected: { [ itemId: string ]: string[] }
- Pagination would likely add further information to the state, though many implementations could choose to ignore it:
page: { page: number; itemsPerPage: number; }
- We should consider an object to represent
place(...)
operations (see Callbacks below) to avoid mutating the data directly for DnD operations:place: Array<{ items: ItemProperties[], position: string | number, relativeTo?: ItemProperties }>
Item Metadata
Each item within the data is "marked up" by the data provider with information about each item. This allows configuration concerning data structure to be implemented by the data provider, not by the grid. For example, idProperty
can be passed to the data provider which uses that to assign the id
to its properties.
id: string
index: number
expandedLevel?: number
indicates how many "parents" were expanded to reach this itemisExpanded?: boolean
canExpand?: boolean
isSelected?: enum.ROW | string[]
either an enum (whole row) or a list of column IDsdata: T
(the item data, generically typed)
Data Metadata
This is the object passed to observers. As part of this metadata, the item metadata will be passed in a flat array.
size: { dataLength: number; totalLength: number; }
dataLength
providers information about how many items there are in the subset created bylimit
state changes regardless of how many are in the items arraytotalLength
provides information about how many items there are in total regardless of how many are in the items array
sort: { columnId: string; direction: 'asc' | 'desc' }[]
limit: { start: number; count: number; }
- Explains that the grid will be traversing a subset of the overall data and that slices will happen from this data set
slice: { start: number; count: number; }
- Explains that this is only a subset of the overall data the grid can traverse
items: ItemProperties<T>[]
Callbacks
These are the methods we expect the grid (or other consumers) to call:
sort(sorting: SortDetails[]): void;
slice({ start: number, count: number }): void;
limit({ start: number, count: number }): void;
toggleExpanded(item: ItemProperties): void
toggleSelected(item: ItemProperties, columnId?: column }
place(items: ItemProperties[], position: string | number, relativeTo?: ItemProperties)
(for drag-and-drop of rows where position may be before, after, index, etc.)- Pagination will call a "paging" method with a default implementation in the base data provider that calls
slice
but can be overridden by an implementation if they choose to deal with paging differently:slicePage: { page: number; itemsPerPage: number; }: void;
configure(...): void
(would accept all state config in a single call)expand(item: ItemProperties): void
collapse(item: ItemProperties): void