ViewModelCache
SourceCache for ViewModel instances based on the specified field names set.
The key to the cache is the primary key for the record and the field names set on it. For example if you have a record that accepts id, name and email you could have a record cached for id, for name, for email or any combination of the 3 fields. This is to handle the common case of fetching partial data from a backend.
The cache implementation will update any cache entries that are a subset of a new cache entry. eg. Caching a record with all the possible fields set would result in all the existing partial field cache entries being updated to match the data on the full record for the fields it care about.
Usage:
// Assume User is a ViewModel already defined// Add a recordUser.cache.add(new User({ id: 1, name: 'John' }));// Retrieve a recordconst record = User.cache.get(1, ['id', 'name']);// To update a record just add it againUser.cache.add(new User({ id: 1, name: 'Johnny' }));// Cache is per unique set of fields but a superset will update a subsetUser.cache.add(new User({ id: 1, name: 'Johnny Smith', email: 'johnny@test.com' }));User.cache.get(1, ['id', 'name']);// { id: 1, name: 'Johnny Smith' }User.cache.get(1, ['id', 'name', 'email'])// { id: 1, name: 'Johnny Smith', email: 'johnny@test.com' }// Delete a specific cache for a subset of fieldsUser.cache.delete(1, ['id', 'name']);User.cache.get(1, ['id', 'name']);// nullUser.cache.get(1, ['id', 'name', 'email'])// { id: 1, name: 'Johnny Smith', email: 'johnny@test.com' }// Or all fieldsUser.cache.delete(1);User.cache.get(1, ['id', 'name', 'email'])// null// You can add multiple values at a timeUser.cache.addList([johnny, sam]);// You can listen to changesUser.cache.addListener(2, ['id', 'name'], (previous, next) => console.log(previous, 'change to', next));User.cache.add(new User({ id: 2, name: 'Bob' }));// null changed to User({ id: 2, name: 'Bob' })User.cache.add(new User({ id: 2, name: 'Bobby' }));// User({ id: 2, name: 'Bob' }) changed to User({ id: 2, name: 'Bobby' })User.cache.delete(2)// User({ id: 2, name: 'Bobby' }) changed to null// You can listen to multiple changes. If you use this and addList then you only get one// call for each change that occurs within addListUser.cache.addListenerList(// Ids to listen for changes to[3, 4],// Only get updates for cached records with these field names['id', 'name'],(previous, next) => console.log(previous, 'change to', next));User.cache.addList([new User({ id: 3, name: 'Jay' }), new User({ id: 4, name: 'Bee' })]);// [null, null] changed to [new User({ id: 3, name: 'Jay' }), new User({ id: 4, name: 'Bee' })]User.cache.addList([new User({ id: 3, name: 'Jayz' }), new User({ id: 4, name: 'Beeb' })]);// [new User({ id: 3, name: 'Jay' }), new User({ id: 4, name: 'Bee' })] changed to [new User({ id: 3, name: 'Jayz' }), new User({ id: 4, name: 'Beeb' })]User.cache.delete(3)// [new User({ id: 3, name: 'Jayz' }), new User({ id: 4, name: 'Beeb' })] changed to [null, new User({ id: 4, name: 'Beeb' })]
Field notation
If a model has a RelatedViewModelField the data for a related field can be retrieved using array notation:
// Fetch the 'name' field and the related 'group' record and its 'label' field['name', ['group', 'label']]
To fetch all fields from a relation you can just specify its name:
['name', 'group']// This will be expanded to include all non-relation fields on the related ViewModel['name', ['group', 'label'], ['group', 'ownerId']]
NOTE: Using the shorthand for a relation won't include any nested relation
Accessing deeply related records is supported:
['name', ['group', 'owner', 'name']]
You can combine the shorthand with array notation to get all fields and the specified deep relations:
['name', 'group', ['group', 'owner', 'name']]// Equivalent to:['name', ['group', 'label'], ['group', 'owner', 'name']]
NOTE: When accessing a relation its sourceFieldName
is always included regardless
of whether you explicitly request it:
User.cache.get(1, ['name', 'group']);// {// id: 1,// name: 'Bob',// groupId: 1,// group: {// id: 1,// label: 'Staff',// }// }
API
Constructor
new ViewModelCache(viewModel)
SourceParameter | Type | Description | |
---|---|---|---|
* | viewModel | ViewModel Class | The |
Methods
add(recordOrData)
SourceAdd a record or records to the cache. Records are cached based on the fields that are
set (ie. to retrieve the record you would call get
with the id
and array of field
names that were set on it).
If record A has a superset of fields of record B then when A is cached it will update the cache for record B. The reverse isn't true so as to maintain consistency within a record.
Parameter | Type | Description | |
---|---|---|---|
* | recordOrData | PartialViewModel | The record instance to cache. If a plain object is passed then an instance of the view model will be created and returned. An array is also supported in which case each entry in the array will be converted to the view model if required and returned. |
add(recordOrData)
SourceParameter | Type | Description | |
---|---|---|---|
* | recordOrData | PartialViewModel[] |
add(recordOrData)
SourceParameter | Type | Description | |
---|---|---|---|
* | recordOrData | FieldDataMappingRaw |
add(recordOrData)
SourceParameter | Type | Description | |
---|---|---|---|
* | recordOrData | FieldDataMappingRaw[] |
addList(recordsOrData)
SourceAdd a list of records. Use this in place of manually calling add() on each record individually so that listeners only get notified once of the change to the list rather than for each record in the list.
Parameter | Type | Description | |
---|---|---|---|
* | recordsOrData | PartialViewModel[] | The records to add. Can either be an array of instances of the ViewModel or an array of data objects (or a mixture of both). |
addList(recordsOrData)
SourceParameter | Type | Description | |
---|---|---|---|
* | recordsOrData | FieldDataMappingRaw[] |
addListener(listener)
SourceAdd a listener to any changes at all. The detail of the changes are not available.
Parameter | Type | Description | |
---|---|---|---|
* | listener | Function | Function to that is called when any change occurs. The function is called with no parameters. |
A function that removes the listener
addListener(pkOrPks,fieldNames,listener,?batch)
SourceAdd a listener for any changes, additions or deletions for the record(s) identified by
pkOrPks
for the field names fieldNames
.
Parameter | Type | Description | |
---|---|---|---|
* | pkOrPks | ExtractPkFieldParseableValueType | Primary key or array of multiple primary keys that identifies the record(s) to listen to changes/additions/deletions to |
* | fieldNames | FieldPath[] | Field names to listen to changes/additions/deletions to. See Field notation for supported format. |
* | listener | Function | Function to call with any changes |
batch | boolean | Whether or not to batch this call with other calls (defaults to true). You shouldn't need to change the default. |
A function that removes the listener
addListener(pkOrPks,fieldNames,listener,?batch)
SourceParameter | Type | Description | |
---|---|---|---|
* | pkOrPks | ExtractPkFieldParseableValueType | |
* | fieldNames | "*" | |
* | listener | Function | |
batch | boolean |
addListener(pkOrPks,fieldNames,listener,?batch)
SourceParameter | Type | Description | |
---|---|---|---|
* | pkOrPks | ExtractPkFieldParseableValueType[] | |
* | fieldNames | FieldPath[] | |
* | listener | Function | |
batch | boolean |
addListener(pkOrPksOrListener,fieldNames,listener,?batch)
SourceParameter | Type | Description | |
---|---|---|---|
* | pkOrPksOrListener | ExtractPkFieldParseableValueType[] | |
* | fieldNames | "*" | |
* | listener | Function | |
batch | boolean |
addListenerList(pks,fieldNames,listener)
SourceParameter | Type | Description | |
---|---|---|---|
* | pks | ExtractPkFieldParseableValueType[] | |
* | fieldNames | FieldPath[] | |
* | listener | Function |
addListenerList(pks,fieldNames,listener)
SourceParameter | Type | Description | |
---|---|---|---|
* | pks | ExtractPkFieldParseableValueType[] | |
* | fieldNames | "*" | |
* | listener | Function |
batch(run)
SourceBatch changes made within provided function. This guarantees that any changes made will result in a single call for each relevant listener.
User.cache.addListener(listenerAll);User.cache.addListener(1, ['id', 'name'], listener);User.cache.addListenerList([1, 2], ['id', 'name'], listenerList);User.cache.batch(() => {// This value won't appear in changes at all as it's replaced 2 lines downUser.cache.add({ id: 1, name: 'Bob', groupId: 1 });User.cache.add({ id: 2, name: 'Sam', groupId: null });User.cache.add({ id: 1, name: 'Bobby', groupId: 1 });});// All listeners called once
Parameter | Type | Description | |
---|---|---|---|
* | run | Function |
delete(pk,?fieldNames)
SourceDelete a record from the cache, optionally only for the specified fieldNames
If fieldNames
is omitted then the cache for the record is cleared in it's entirety.
Parameter | Type | Description | |
---|---|---|---|
* | pk | ExtractPkFieldParseableValueType | The primary key of the record to delete |
fieldNames | '*'|[string|string[]][] | Optionally only delete the entry with the specified field names. If this is not set then all data for the record is removed. See Field notation for supported format. |
true if anything was removed, false otherwise
get(pk,fieldNames)
SourceGet a record with the specified fieldNames
set from the cache
Parameter | Type | Description | |
---|---|---|---|
* | pk | ExtractPkFieldParseableValueType | the primary key of the record to get |
* | fieldNames | FieldPath[] | the field names to use to look up the cache entry. Use '*' to indicate all fields. See Field notation for supported format. |
One of the following:
PartialViewModelOR
nullThe cached record or null if none found
get(pk,fieldNames)
SourceParameter | Type | Description | |
---|---|---|---|
* | pk | ExtractPkFieldParseableValueType | |
* | fieldNames | "*" |
One of the following:
PartialViewModelOR
nullget(record)
SourceGet the currently cached version of the specified version
Parameter | Type | Description | |
---|---|---|---|
* | record | PartialViewModel | a current instance of a ViewModel to get the latest cached version of |
One of the following:
PartialViewModelOR
nullThe cached record or null if none found
getAll(fieldNames)
SourceGet all records in the cache for the specified field names. This acts like getList
but returns
all records not just records with specified primary keys.
This function guarantees to return the same array (ie. passes strict equality check) if the underlying records have not changed.
Parameter | Type | Description | |
---|---|---|---|
* | fieldNames | "*" | List of field names to return records for. See Field notation for supported format. |
getList(pks,fieldNames,?removeNulls)
SourceGet a list of records with the specified fieldNames
set from the cache
Any record that is not found will end up in the array as a null value. If this isn't desired you must filter them manually.
Parameter | Type | Description | |
---|---|---|---|
* | pks | ExtractPkFieldParseableValueType[] | An array of primary keys |
* | fieldNames | FieldPath[] | the field names to use to look up the cached entries. See Field notation for supported format. |
removeNulls | RemoveNullsT | whether to remove entries that have no record in the cache. Defaults to true. |
an array of the cached records. Any records not found will be in the array as a null value if removeNulls
is false otherwise they will be removed.
getList(pks,fieldNames,?removeNulls)
SourceParameter | Type | Description | |
---|---|---|---|
* | pks | ExtractPkFieldParseableValueType[] | |
* | fieldNames | "*" | |
removeNulls | RemoveNullsT |
getList(records,?removeNulls)
SourceGet list of cached records from an existing list of records
Parameter | Type | Description | |
---|---|---|---|
* | records | ViewModelInterface[] | List of existing ViewModel records to get latest cache version for |
removeNulls | RemoveNullsT | whether to remove entries that have no record in the cache. Defaults to true. |
an array of the cached records. Any records not found will be in the array as a null value if removeNulls
is false otherwise they will be removed.
getList(records,?removeNulls)
SourceParameter | Type | Description | |
---|---|---|---|
* | records | PartialViewModel[] | |
removeNulls | RemoveNullsT |