Store
The Store represents a data container which holds flat data or tree structures. An item in the Store is often called a ´record´ and it is simply an instance of the Model (or any subclass thereof).
Typically, you load data into a store to display it in a Grid or a ComboBox. The Store is the backing data component for any component that is showing data in a list style UI.
The Store offers an API to edit, filter, group and sort the records.
Data is stored in a JSON array
Store with flat data
const store = new Store({
data : [
{ id : 1, name : 'ABBA', country : 'Sweden' },
{ id : 2, name : 'Beatles', country : 'UK' }
]
});
// retrieve record by id
const beatles = store.getById(2);
By default, when using inline data (supplied directly to the store by the app, not loaded remotely by an AjaxStore
or CrudManager) the incoming data objects are cloned by the created records. This means that those objects will not
get "polluted" when default values are applied, or when records are manipulated later. But cloning reduces record
creation performance a bit, if the raw data objects are not directly used elsewhere you can opt out of cloning by
setting the useRawData config to true.
Note that if the first object in the incoming data is un-extensible (~immutable), the entire incoming dataset will be
cloned even if configured with useRawData: true.
Store with tree data
children property for descendant records
const store = new Store({
tree: true,
data : [
{ id : 1, name : 'ABBA', country : 'Sweden', children: [
{ id: 2, name: 'Agnetha' },
{ id: 3, name: 'Bjorn' },
{ id: 4, name: 'Benny' },
{ id: 5, name: 'Anni-Frid' }
]},
]
});
// retrieve record by id
let benny = store.getById(4);
Optionally a tree store can consume a flat dataset with nodes that have a parentId property. By configuring the
store with tree : true and transformFlatData : true, the flat data is transformed into tree data:
const store = new Store({
tree : true,
transformFlatData : true,
data : [
{ id : 1, name : 'ABBA', country : 'Sweden' },
{ id : 2, name : 'Agnetha', parentId : 1 },
{ id : 3, name : 'Bjorn', parentId : 1 },
{ id : 4, name : 'Benny', parentId : 1 },
{ id : 5, name : 'Anni-Frid', parentId : 1 }
]
});
Retrieving and consuming JSON
For both flat stores or tree stores it is possible to retrieve the data of all records in JSON format:
const jsonString = store.json;
// or
const jsonArray = store.toJSON();
To plug the JSON data back in later:
store.data = JSON.parse(jsonString);
// or
store.data = jsonArray;
Lazy loading
true. This will make the store request records when
they are needed, rather than the complete dataset at once. The request is intercepted by implementing the
requestData function. Each request will be made up of 1 chunk before and after the requested index
(which gives a total of 2 chunks). The chunk size can be configured in the lazyLoad config.
There is a guide for implementing lazy loading in Grid.
Paging
true. For a
non-AjaxStore, data will be requested by the Store by calling the implemented
requestData function. Data can also be provided by listening to the requestData
event, and updating the data property with new data.
const store = new Store({
remotePaging : true,
requestData({ page, pageSize }){
const start = (page - 1) * pageSize;
const data = allRecords.splice(start, start + pageSize);
return {
data,
total : allRecords.length
}
}
})
Remote sorting
true. This makes it possible to
use the built-in sorting features of the Store and corresponding UI functionality, without using local data. For a
non-AjaxStore, data will be requested by the Store by calling a by the app implemented
requestData function. Data can also be provided by listening to the requestData
event, and updating the data property with new data.
const store = new Store({
remoteSort : true,
remotePaging : true,
requestData({ sorters, page, pageSize }){
const sortedRecords = [...allRecords];
sorters?.forEach(sorter => sortedRecords.sort((a,b) => {
const { field, ascending } = sorter;
if (!ascending) {
([b, a] = [a, b]);
}
return a[field] > b[field] ? 1 : (a[field] < b[field] ? -1 : 0)
});
const start = (page - 1) * pageSize;
const data = sortedRecords.splice(start, start + pageSize);
return {
data,
total : allRecords.length
}
}
})
For AjaxStore, data will be loaded via the configured readUrl.
Remote filtering
true. This makes it possible
to use the built-in filtering features of the Store and corresponding UI functionality, without using local data.
For a non-AjaxStore, data will be requested by the Store by calling the implemented requestData function. Data can also be provided by listening to the requestData event, and updating the data property with new data.
const store = new Store({
remoteFilter : true,
remoteSort : true,
remotePaging : true,
requestData({ filters, sorters, page, pageSize }){
let filteredRecords = [...allRecords];
filters?.forEach(filter => {
const { field, operator, value, caseSensitive } = filter;
if(operator === '='){
filteredRecords = filteredRecords.filter(r => r[field] === value);
}
else {
/// ... implement other filter operators
}
});
sorters?.forEach(sorter => filteredRecords.sort((a,b) => {
const { field, ascending } = sorter;
if (!ascending) {
([b, a] = [a, b]);
}
return a[field] > b[field] ? 1 : (a[field] < b[field] ? -1 : 0)
}));
const start = (page - 1) * pageSize;
const data = filteredRecords.splice(start, start + pageSize);
return {
data,
total : filteredRecords.length
}
}
})
For AjaxStore, data will be loaded via the configured readUrl.
Getting record count
To get the number of "visible" records in the store (records that would be shown when using the Store as the data source for a Grid or similar), use the count property. This will return the number of records in the store after filtering and grouping has been applied, including the generated group headers and footers but excluding any records inside collapsed parents or group headers:
const visibleRecords = store.count;
To get other counts, such as the total number of data records in the store including those collapsed away and filtered out, use the more flexible getCount method:
// Include records that have been filtered out,
// as well as any records inside collapsed groups or tree nodes.
const records = store.getCount({
collapsed : true,
filteredOut : true
});
// Including group headers + summary records
const records = store.getCount({
headersFooters : true
});
// All records, including group headers and filtered out records
const allRecords = store.getCount({
all : true
});
Sharing stores
Shared data
To create 2 widgets that share data, you can create 2 separate stores and pass records of the first store as the dataset of the second store.
let combo1 = new Combo({
appendTo : document.body,
store : new Store({
data : [
{ id : 1, name : 'ABBA', country : 'Sweden' },
{ id : 2, name : 'Beatles', country : 'UK' }
]
}),
valueField : 'id',
displayField : 'name'
});
let combo2 = new Combo({
appendTo : document.body,
store : new Store({
data : combo1.store.records
}),
valueField : 'id',
displayField : 'name'
});
combo1.store.first.name = 'foo';
combo2.store.first.name; // "foo"
Chained stores
Another more powerful option to share data between widgets is to create chained stores. The easiest way to create a chained store is to call chain function.
let combo1 = new Combo({
appendTo : document.body,
store : new Store({
data : [
{ id : 1, name : 'ABBA', country : 'Sweden' },
{ id : 2, name : 'Beatles', country : 'UK' }
]
}),
valueField : 'id',
displayField : 'name'
});
let combo2 = new Combo({
appendTo : document.body,
store : combo1.store.chain(),
valueField : 'id',
displayField : 'name'
});
combo1.store.first.name = 'foo';
combo2.store.first.name; // "foo"
A chained store can optionally be created with a filtering function, to only contain a subset of the records from the main store. In addition, the chained store will reflect record removals/additions to the master store, something the shared data approach will not.
Non-homogeneous data structures
You can use different Model classes to represent the records in the store by overriding the createRecord method:
const store = new Store ({
modelClass : Gate,
readUrl : 'data/the-airport.json',
autoLoad : true,
// The default model is a Gate (see above) and in this createRecord method, we can decide at runtime based
// on the data which model class to use. This is useful when your record types aren't homogenous.
createRecord(data) {
let modelClass = this.modelClass;
if (data.type === 'terminal') {
modelClass = Terminal;
}
return new modelClass(data, this);
}
},
Configs
56
Configs
56Common
Commit changes automatically
For a non-AjaxStore, the autoLoad config will only take effect if the store is configured as lazyLoad, remoteSort, remoteFilter or remotePaging. In these cases, it will immediately after creation, perform a request by calling the requestData function.
An array of field definitions used to create a Model (modelClass) subclass. Optional. If the Model already has fields defined, these fields will extend those.
const store = new Store({
fields : ['name', 'city', 'company'],
data : [
{ id : 1, name : 'Mark', city : 'London', company : 'Cool inc' },
...
]
});
See Model for more info on defining fields, changing data source and mapping fields to nested objects.
Note that pre-created record instances supplied to the store are kept as is and thus these fields will not apply to them.
Initial groupers, specify to have store grouped automatically after initially setting data
Store's unique identifier. When set the store is added to a store map accessible through
Store.getStore(id).
If set to true, or a config object, this makes the store load new records when needed. When a record that
is not already loaded is requested, the requestData function is called. Please read the
guide to learn more on how to configure lazy loading.
| Parameter | Type | Description |
|---|---|---|
lazyLoad | Object | Lazy load config |
lazyLoad.chunkSize | Number | The number of records to be loaded before and after the requested index. |
Class used to represent records in the store, should be a subclass of Model. Only applies when supplying data to the store (load, add), any supplied record instances are kept as is.
class MyModel extends Model {
static get fields() {
return [
'name',
'city',
'company'
]
}
}
const store = new Store({
modelClass : MyModel,
data : [
{ id : 1, name : 'Mark', city : 'London', company : 'Cool inc' },
...
]
});
In a non-AjaxStore, configured with lazyLoad, remoteSort, remoteFilter or remotePaging, the function provided here is called when the Store needs new data, which will happen:
- for lazyLoad, when a record that has not yet been loaded is requested.
- for remoteSort, on a sort operation.
- for remoteFilter, on a filter operation.
- for remotePaging, when current page is changed.
When implementing this, it is expected that what is returned is an object with a data property containing the
records requested. What is requested will be specified in the params object, which will differ depending on the
source of the request.
For lazyLoad, the params object will contain a startIndex and a count param. It is expected
for the implementation of this function to provide a data property containing the number of records specified
in the count param starting from the specified startIndex.
class MyStore extends Store {
async requestData({startIndex, count}){
const response = await getData(startIndex, count);
return {
data : response.records,
total : response.totalRecordCount
}
}
}
For remotePaging, the params object will contain a page and a pageSize param. It is expected
for the implementation of this function to provide a data property containing the number of records specified
in the pageSize param starting from the specified page.
class MyStore extends Store {
requestData({page, pageSize}){
const start = (page - 1) * pageSize;
const data = allRecords.splice(start, start + pageSize);
return {
data,
total : allRecords.length
}
}
}
For lazyLoad it is recommended, and for remotePaging it is required, to include a
total property which reflects the total amount of records available to load. If the total property is omitted
(when lazyLoad), certain features and functions are disabled:
- The component (Grid for example) is not aware of the total number of records, which will make the scrollbar's thumb change size and position when new records are loaded.
- The store don't know when to stop requesting new records. The
totalproperty will be set to the index of the last record loaded after requestData returns with fewer records than requested.
If remoteSort is active, the params object will contain a sorters param, containing a number of
sorter objects.The sorter objects will look like this:
{
"field": "name",
"ascending": true
}
If remoteFilter is active, the params object will contain a filters param, containing a number
of filters objects. The filter objects will look like this:
{
"field": "country",
"operator": "=",
"value": "sweden",
"caseSensitive": false
}
The Base implementation of this function does nothing, you need to create your own subclass with an implementation.
Configuration parameter to pass a function to be used as requestData in non-AjaxStore.
| Parameter | Type | Description |
|---|---|---|
params | LazyLoadRequestParams | PagingRequestParams | Object containing info of which records is requested |
Initial sorters, format is:
{ sorters : [{ field: 'name', ascending: false }, ...] }
// or
{ sorters : ['name', ...] }
Configure with true to sync loaded data instead of replacing existing with a new dataset.
By default (or when configured with false) assigning to store.data replaces the entire dataset
with a new one, creating all new records:
store.data = [ { id : 1, name : 'Saitama' } ];
const first = store.first;
store.data = [ { id : 1, name : 'One-Punch man' } ];
// store.first !== first;
When configured with true the new dataset is instead synced against the old, figuring out what was
added, removed and updated:
store.data = [ { id : 1, name : 'Saitama' } ];
const first = store.first;
store.data = [ { id : 1, name : 'One-Punch man' } ];
// store.first === first;
After the sync, any configured sorters, groupers and filters will be reapplied.
Threshold
The sync operation has a configurable threshold, above which the operation will be treated as a
batch/refresh and only trigger a single refresh event. If threshold is not reached, individual events
will be triggered (single add, remove and possible multiple update). To enable the threshold,
supply a config object with a threshold property instead of true:
const store = new Store({
syncDataOnLoad : {
threshold : '20%'
}
});
threshold accepts numbers or strings. A numeric threshold means number of affected records, while a
string is used as a percentage of the whole dataset (appending % is optional). By default no threshold
is used.
Missing fields
The value of any field not supplied in the new dataset is by default kept as is (if record is not removed
by the sync). This behaviour is configurable, by setting keepMissingValues : false in a config object
it will reset any unspecified field back to their default values:
const store = new Store({
syncDataOnLoad : {
keepMissingValues : false
}
});
Considering the following sync operation:
// Existing data
{ id : 1, name : 'Saitama', powerLevel : 100 }
// Sync data
{ id : 1, name : 'One-Punch Man' }
The result would by default (or when explicitly configured with true) be:
{ id : 1, name : 'One-Punch Man', powerLevel : 100 }
If configured with keepMissingValues : false it would instead be:
{ id : 1, name : 'One-Punch Man' }
syncDataOnLoad on a chained store, it will create an infinite loop when
it is populated from the main store (the main store can use the setting)
Advanced
Specify false to prevent loading records without ids, a good practice to enforce when syncing with a
backend.
By default, Store allows loading records without ids, in which case a generated id will be assigned.
Specifies target to filter and sort after applying changeset:
'changes'- apply sort and filter to changeset only (see more below)'none'- do not apply sort and filter
changes behavior
If the store has filters in effect when the changeset is applied, the following rules will determine how the filtered values are affected:
- Among added records, only those that match the filter will be included in the filtered set
- Among updated records, those that did not previously match the filter but now do will be added to the filtered set,
and those that did match but no longer do will also remain in the filtered set. This means that new records may
appear in the filtered set as a result of
applyChanges, but records will not disappear until filters are re-applied.
Does not apply if the store is remotely filtered.
Set to false to not record transaction during applyChangeset call
To have all groups initially loaded start collapsed, configure this as true.
Note that this only affects the initial load of the store. Subsequent reloads maintain current group state where possible.
Reference to STM manager
A Collection, or Collection config object to use to contain this Store's constituent records.
Store class to use when creating the store when it is a part of a CrudManager.
crudManager : {
eventStore {
storeClass : MyEventStore
}
}
Use localeCompare() when sorting, which lets the browser sort in a locale specific order. Set to true,
a locale string or a locale config to enable.
Enabling this has big negative impact on sorting
performance. For more info on localeCompare(), see MDN.
Examples:
const store = new Store({
// Swedish sorting
useLocaleSort : 'sv-SE'
});
const store = new Store({
// Swedish sorting with custom casing order
useLocaleSort : {
locale : 'sv-SE',
caseFirst : 'upper'
}
});
Can also be configured on a per-sorter basis:
store.sort({ field: 'name', useLocaleSort : 'sv-SE' });
Retools the loaded data objects instead of making shallow copies of them. This increases performance but pollutes the incoming data.
This setting is off by default, but is turned on automatically unless explicitly configured when data is
loaded using an AjaxStore (configured with a readUrl) or a CrudManager (configured to load data
remotely).
// No duplicate id checking, no type conversions
new Store({ useRawData : true });
Also allows disabling certain steps in data loading, to further improved performance. Either accepts an
object with the params described below or true which enables disableDuplicateIdCheck.
new Store({
// No type conversions only
useRawData : {
disableTypeConversion : true
}
});
Note that if the first object in the incoming data is determined to be un-extensible (~immutable), the entire incoming dataset will be cloned.
Also note that since incoming data objects gets polluted with this setting on, reusing the same data objects elsewhere might lead to unexpected behavior.
| Parameter | Type | Description |
|---|---|---|
disableDuplicateIdCheck | Boolean | Data must not contain duplicate ids, check is bypassed. |
disableDefaultValue | Boolean | Default values will not be applied to record fields. |
disableTypeConversion | Boolean | No type conversions will be performed on record data. Incoming data must be in the correct format expected by each field, for example dates must be Date objects. |
Chained store
Array of field names that should trigger filtering of chained store when the fields are updated.
Function used to filter records in the masterStore into a chained store. If not provided,
all records from the masterStore will be included in the chained store.
Return true to include the passed record, or a false to exclude it.
| Parameter | Type | Description |
|---|---|---|
record | Model |
If true, chained stores will apply filters from the master store. Filters flagged with ignoreForChain
will be ignored.
Method names calls to which shouldn't be relayed to master store.
Method names calls to which should be relayed to master store.
If true, collapsed records in original tree will be excluded from the chained store.
chainTree()Set to true to prevent including links (when grouping by array field)
Master store that a chained store gets its records from.
If true, changing the order of records in a flat chained store (for example by using the RowReorder
feature in a Grid-based widget) will also change the order of records in the master store.
Example usage:
store.chain(record => record.percent < 10, null, {
syncOrder : true
});
A B C D E, and the chained store has E C A, it will be difficult for users to
predict the outcome of moving E to between C A.If true, chained stores will be sorted when the master store is sorted. Note that this replaces
any existing sorters defined on the chained store.
Filtering
Specify one or more CollectionFilter config objects to apply initially.
For example:
// Configure the store to filter in clients over the age of 30
new Store({
...,
filters : [{
property : 'age',
value : 30,
operator : '>'
}],
...
})
or:
// Configure the store to filter based on a complex operation
new Store({
...,
filters : [{
filterBy(record) {
// Return true or false for filtering in or out
return shouldClientBeVisible(record);
}
}],
...
})
Specify true to reapply filters when a record is added to or moved within the store.
This includes tree node operations like indent/outdent in Gantt, or any move operation
that changes a node's parent.
Specify true to reapply filters when a record is updated in the store. You can also provide an array
of field names, to only re-filter when certain data fields are updated.
| Parameter | Type | Description |
|---|---|---|
reapplyFilterOnUpdate.fields | String[] |
Specify true to reapply sorting when a record is updated in the store. You can also provide an array
of field names, to only trigger sort when certain data fields are updated.
| Parameter | Type | Description |
|---|---|---|
reapplySortersOnUpdate.fields | String[] | Fields that reapply sorting when updated |
Set this to true to activate remote filtering in this Store. This makes it possible to use the built-in
filtering features of the Store and corresponding UI functionality, without using local data.
For a non-AjaxStore, data will be requested by the Store by calling a by the app implemented requestData function. Data can also be provided by listening to the requestData event, and updating the data property with new data.
For AjaxStore, data will be loaded via the configured readUrl.
Other
When set to true, restores the expanded states of tree nodes when reloading data.
Enable sparse index handling. When enabled, the store's model will be augmented with a sparseIndex field
(unless it already exists) which will be automatically managed by the store. When adding or inserting records
into the store, sparse indexes will be generated for those records. When moving records, their sparse index
will be updated with a fractional number. They will be used to sort records when no other sorter is defined
on the store.
Sparse indexes are a tree-defining property. They will also be used to determine the order of records when persisting the store's data. When using sparse indexes in a tree store, the store's parentId will also be made persistent to allow reconstruction of the tree structure when loading data.
When using sparse indexes, the other tree-defining properties parentIndex and orderedParentIndex will no
longer be persistent. Their values will still be updated when items are added, removed, or re-ordered, but
they won't be marked as dirty and won't be included when persisting the store's data. If it is necessary to
persist these fields, use hierarchyModificationDataToWrite.
Verify that loaded data does not contain any generated ids. If it does, a warning is logged on console.
Set this to false to disable the check and give a very minor performance boost.
Paging
The name of the parameter to use when requesting pages of data using the zero based index of the required page's starting record.
When the Store is paged by configuring remotePaging, this value will be included in the load requests.
Note: Setting pageSize at runtime will automatically reload the page.
The name of the parameter to use when requesting pages of data, representing the configured pageSize value.
The name of the parameter to use when requesting pages of data using the one based page number required.
Set this to true to activate remote paging in this Store. Makes it possible to use the
loadPage, nextPage, and previousPage functions. Or
add the PagingToolbar to control what page to load.
For a non-AjaxStore, data will be requested by the Store by calling a by the app implemented requestData function. Data can also be provided by listening to the requestData event, and updating the data property with new data.
Records
Creates a model instance, used internally when data is set/added. Provide this method for your own custom conversion from data to record.
| Parameter | Type | Description |
|---|---|---|
data | * | Json data |
skipExpose | Boolean | Supply true when batch setting to not expose properties multiple times |
Remote
The name of the parameter to use to pass any filters when loading data remotely.
Note: When this is set, filters must be defined using a field name, an operator and a value to compare, not a comparison function.
Sorting
Specify true to sort this store after records are added.
Set this to true to activate remote sorting in this Store. This makes it possible to use the built-in
sorting features of the Store and corresponding UI functionality, without using local data.
For a non-AjaxStore, data will be requested by the Store by calling a by the app implemented requestData function. Data can also be provided by listening to the requestData event, and updating the data property with new data.
For AjaxStore, data will be loaded via the configured readUrl.
The name of the parameter to use to pass any sorters when loading data remotely.
Note: When this is set, sorters must be defined using a field name and an ascending flag, not a sort function.
Tree
Automatically detect from set data if used as tree store or flat store. If tree is explicitly
set to false, then this value will be overruled and no tree detection performed.
Set to true to fire a 'remove' event when moving a node (to mimic the behavior of versions < 6.0).
Set to true to on load transform a flat dataset with raw objects containing parentId into the format
expected for tree data.
Example input format:
[
{ id : 1, name : 'Parent' },
{ id : 2, name : 'Child', parentId : 1 }
]
Will be transformed into:
[
{
id : 1,
name : 'Parent',
children : [
{ id : 2, name : 'Child', parentId : 1 }
]
}
]
true to act as a tree store.
Properties
75
Properties
75Common
Store's unique identifier.
If set to true, or a config object, this makes the store load new records when needed. When a record that
is not already loaded is requested, the requestData function is called. Please read the
guide to learn more on how to configure lazy loading.
| Parameter | Type | Description |
|---|---|---|
lazyLoad | Object | Lazy load config |
lazyLoad.chunkSize | Number | The number of records to be loaded before and after the requested index. |
Advanced
Specifies target to filter and sort after applying changeset:
'changes'- apply sort and filter to changeset only (see more below)'none'- do not apply sort and filter
changes behavior
If the store has filters in effect when the changeset is applied, the following rules will determine how the filtered values are affected:
- Among added records, only those that match the filter will be included in the filtered set
- Among updated records, those that did not previously match the filter but now do will be added to the filtered set,
and those that did match but no longer do will also remain in the filtered set. This means that new records may
appear in the filtered set as a result of
applyChanges, but records will not disappear until filters are re-applied.
Does not apply if the store is remotely filtered.
Set to false to not record transaction during applyChangeset call
Is this a chained store?
A special Symbol signalizing treeify method that the current record grouping should be stopped.
const newRoot = workerStore.treeify([
// group workers by company
worker => {
// if the worker is unemployed we don't put it in a group
// we just show such record on the root level
if (!worker.company) {
return Store.StopBranch
}
return worker.company;
}
]);
Class hierarchy
Filtering
Specify true to reapply sorting when a record is updated in the store. You can also provide an array
of field names, to only trigger sort when certain data fields are updated.
| Parameter | Type | Description |
|---|---|---|
reapplySortersOnUpdate.fields | String[] | Fields that reapply sorting when updated |
Other
If the store is paged, yields the current page number.
Pretty printed version of json
Returns all the group header records
Retrieve or set the data of all records as a JSON string
const store = new Store({
data : [
{ id : 1, name : 'Superman' },
{ id : 2, name : 'Batman' }
]
});
const jsonString = store.json;
//jsonString:
'[{"id":1,"name":"Superman"},{"id":2,"name":"Batman"}]
Verify that loaded data does not contain any generated ids. If it does, a warning is logged on console.
Set this to false to disable the check and give a very minor performance boost.
Paging
Yields true if this Store is loaded page by page. See the remotePaging config.
If the store is paged, yields the highest page number in the dataset as calculated from the 'total' returned in the last page data block loaded.
When the Store is paged by configuring remotePaging, this value will be included in the load requests.
Note: Setting pageSize at runtime will automatically reload the page.
Records
Returns all locally available records from the store, ignoring any filters and including grouping headers / footers.
Setting autoCommit to true automatically commits changes to records.
Get uncommitted changes as an object of added/modified/removed arrays of records.
// Format:
{
added: [], // array of Core.data.Model
modified: [], // array of Core.data.Model
removed: [] // array of Core.data.Model
}
| Parameter | Type | Description |
|---|---|---|
changes.added | Model[] | Records that have been added |
changes.modified | Model[] | Records that have changes to persistable fields |
changes.removed | Model[] | Records that have been removed |
Record count, including records added for group headers etc., excluding collapsed or filtered away records. That
is, count is the "visible record count", if the store is used in a Grid or other component that visualize the
records.
Consider the following dataset loaded into a Store:
[
{ id : 1, name : 'Linda', city : 'NY' },
{ id : 2, name : 'Olivia', city : 'NY' },
{ id : 3, name : 'John', city : 'Stockholm' }
]
// count === 3
Grouping by city yields the following records in the Store (pseudocode):
store.group('city');
[
{ name : 'Group NY', groupHeader : true, expanded : true },
{ id : 1, name : 'Linda', city : 'NY' },
{ id : 2, name : 'Olivia', city : 'NY' },
{ name : 'Group Stockholm', groupHeader : true },
{ id : 3, name : 'John', city : 'Stockholm', expanded : true }
]
// count === 5
Collapsing the Stockholm group yields the following records in the Store (pseudocode):
store.collapse(store.getAt(3));
[
{ name : 'Group NY', groupHeader : true, expanded : true },
{ id : 1, name : 'Linda', city : 'NY' },
{ id : 2, name : 'Olivia', city : 'NY' },
{ name : 'Group Stockholm', groupHeader : true, expanded : false }
]
// count === 4
Applying a filter further affects the count (pseudocode):
store.filter('name', 'Linda');
[
{ name : 'Group NY', groupHeader : true, expanded : true },
{ id : 1, name : 'Linda', city : 'NY' }
]
// count === 2
If you need a different value for count in your app, for example ignoring filters, or including collapsed away
records, please use the more flexible getCount function instead.
If the store is configured with lazyLoad, this number is based on the total amount of records specified in the response given to the requestData function.
Sets data in the store.
Expects an array of JavaScript objects, with properties matching store's fields (defined on its model or in the fields config).
Called on initialization if data is in the config, otherwise call it yourself after for example using fetch to
get remote data:
store.data = [
{ id : 1, name : 'Linda', city : 'NY' },
{ id : 2, name : 'Olivia', city : 'Paris' },
...
];
Can also be used to get an array of the current raw data objects from all records in the store (ignoring filtering and grouping):
console.log(store.data);
// [
// { id : 1, name : 'Linda', city : 'NY' },
// { id : 2, name : 'Olivia', city : 'Paris' },
// ...
// ]
Class used to represent records. Defaults to class Model.
Returns all locally available "visible" records. Note: The returned value may not be mutated!
Yields the complete dataset size, ignoring filtering and grouping. If the store
is paged, it returns the total value provided in the page load request response, or
manually set.
Sort, group & filter
Currently applied filters. A collection of CollectionFilter instances.
Currently used groupers. To set groupers when remote sorting is enabled by sortParamName you should use setGroupers instead to be able to wait for the operation to finish.
Check if store is filtered
Is store currently grouped?
Currently applied sorters
Tree
true if this Store is configured to handle tree data (with tree : true) or if this is a
chained store and the master store is a tree store.
Misc
Functions
98
Functions
98Chained store
Creates a chained store, a new Store instance that contains a subset of the records from current store. Which records is determined by a filtering function, which is reapplied when data in the base store changes.
// Chain all records
const all = store.chain();
// Or a subset using a filter function
const oldies = store.chain(record => record.age > 50);
If this store is a tree store, then the resulting chained store
will be a tree store sharing the same root node, but only child nodes which pass the chainedFilterFn will be
considered when iterating the tree through the methods such as
traverse or forEach.
| Parameter | Type | Description |
|---|---|---|
chainedFilterFn | function | An optional filter function called for every record to determine if it should
be included (return |
chainedFields | String[] | Array of fields that trigger filtering when they are updated |
config | StoreConfig | Additional chained store configuration. See Store#configs |
Creates a chained tree store, a new Store instance that contains a subset of the records from current store. Which records is determined by a filtering function, which is reapplied when data in the base store changes.
// Chain all nodes
const fullTree = store.chainTree();
// Or a subset
const oldies = store.chainTree(record => record.age > 50);
The resulting chained store will be a tree store with its own root node, under which all children are links to the nodes in this store. This allows for expanding/collapsing and filtering nodes in the chained store without affecting the original store.
| Parameter | Type | Description |
|---|---|---|
chainedFilterFn | function | An optional filter function called for every leaf record to determine if it
should be included (return |
chainedFields | String[] | Array of fields that trigger filtering when they are updated |
config | StoreConfig | Additional chained store configuration. See Store#configs |
Updates records available in a chained store by filtering the master store records using chainedFilterFn
CRUD
Add records to store.
| Parameter | Type | Description |
|---|---|---|
records | Model | Model[] | Object | Object[] | Array of records/data or a single record/data to add to store |
silent | Boolean | Specify |
Added records
Applies a set of changes (presumable from a backend) expressed as an object matching the format outputted by the
changes property: { added : [], modified/updated : [], removed : [] }
added is expected to be an array of raw data objects consumable by the stores model class for records to add
to the store (see example snippet below).
modified (or updated for compatibility with Schedulers CrudManager) is expected to have the same format as
added, but should always include the id of the record to update.
Records that have been created locally and gets assigned a proper id by the backend are expected to also pass a
phantomId field (name of the field is configurable using the phantomIdField arg, more info on phantom ids
below), to match it with the current id of a local record (id will contain the new id).
Note that it is also possible to pass this phantomId -> id mapping in the added array. When encountering a
record in that array that already exists in the local store, it will be treated the same way as a record in the
modified array.
removed is expected to be an array of objects with the { id : xx } shape. Any matches on an id in the store
will be removed, those and any non-matches will also be cleared from the change tracking of the store.
If the store has filters in effect when the changeset is applied, the following rules will determine how the filtered values are affected:
- Among added records, only those that match the filter will be included in the filtered set
- Among updated records, those that did not previously match the filter but now do will be added to the filtered
set, and those that did match but no longer do will also remain in the filtered set. This means that new records
may appear in the filtered set as a result of
applyChanges, but records will not disappear until filters are re-applied.
As an example, consider a store with the following initial state and some operations performed on it:
// Load some data
store.data = [
{ id : 1, name : 'Minerva' },
{ id : 2, name : 'Mars' },
{ id : 3, name : 'Jupiter' }
];
// Add a new record. It gets assigned a generated id,
// for example, 'generated56'
store.add({ name : 'Artemis' });
// Remove Jupiter
store.remove(3);
After syncing those operations to a custom backend (however, you chose to solve it in your application), we might get the following response (see "Transforming a response to the correct format" below if your backend responds in another format):
const serverResponse = {
added : [
// Added by the backend, will be added locally
{ id : 5, name : 'Demeter' }
],
updated : [
// Will change the name of Minerva -> Athena
{ id : 1, name : 'Athena' },
// Will set proper id 4 for Artemis
{ $PhantomId : 'generated56', id : 4 }
],
removed : [
// Confirmed remove of Jupiter
{ id : 3 },
// Removed by the backend, Mars will be removed locally
{ id : 2 }
]
};
If that response is then passed to this function:
store.applyChangeset(serverResponse);
The result will be the following data in the store:
[
{ id : 1, name : 'Athena' }, // Changed name
{ id : 4, name : 'Artemis' }, // Got a proper id
{ id : 5, name : 'Demeter' } // Added by the backend
]
Phantom ids
When a record is created locally, it is always assigned a generated id. That id is called a phantom id (note that it is assigned to the normal id field). When passing the new record to the backend, the id is sent with it. When the backend inserts the record into the database, it (normally) gets a proper id assigned. That id then needs to be passed back in the response, to update the local record with the correct id. Making sure that future updates match the correct row in the database.
For example, a newly created record should be passed similar to this to the backend (pseudo format, up to the application/backend to decide):
{
"added" : {
"id" : "generated79",
"name" : "Hercules",
...
}
}
For the backend response to be applicable for this function, it should then respond with:
{
"updated" : {
{
"$PhantomId" : "generated79",
"id" : 465
}
}
}
(Or, as stated above, it can also be passed in the "added" array. Whichever suits your backend best).
This function will then change the id of the local record using the phantom id generated79 to 465.
Transforming a response to the correct format
This function optionally accepts a transformFn, a function that will be called with the changes. It is
expected to return a changeset in the format described above ({ added : [], updated : [], removed : [] }),
which then will be used to apply the changes.
Consider the following "non-standard" (made-up) changeset:
const changes = {
// Database ids for records previously added locally
assignedIds : {
'phantom1' : 10,
'phantom2' : 15
},
// Ids records removed by the backend
removed : [11, 27],
// Modified records, keyed by id
altered : {
12 : { name : 'Changed' }
},
// New records, keyed by id
inserted : {
20 : { name : 'New' }
}
}
Since it does not match the expected format, it has to be transformed:
store.applyChangeset(changes, ({ assignedIds, inserted, altered, removed }) => ({
// Convert inserted to [{ id : 20, name : 'New' }]
added : Object.entries(inserted).map(([id, data] => ({ id, ...data }),
updated : [
// Convert assignedIds to [{ $PhantomId : 'phantom1', id : 10 }, ...]
...Object.entries(assignedIds).map(([phantomId, id])) => ({ $PhantomId : phantomId, id }),
// Convert altered to [{ id : 12, name : 'Changed' }]
...Object.entries(modified).map(([id, data] => ({ id, ...data })
],
// Convert removed to [{ id : 11 }, ...]
removed : removed.map(id => ({ id }))
}));
The transform function above would output:
{
added : [
{ id : 20, name : 'New' }
],
updated : [
{ $PhantomId : 'phantom1', id : 10 },
{ $PhantomId : 'phantom2', id : 15 },
{ id : 12, name : 'Changed' }
],
removed : [
{ id : 11 },
{ id : 12 }
]
}
And that format can then be applied.
Preventing automatic commit of applied changes
By default, the clearChanges parameter is set to true, which automatically commits applied changes to the
store. Setting this parameter to false prevents the automatic commit, keeping the store in a dirty state.
For example, the following will apply changes without committing them:
const changes = {
added : [
{ id : 20, name : 'New' }
],
updated : [
{ id : 10, name : 'Fiona' },
],
removed : [
{ id : 11 }
]
};
// Apply these changes using the applyChangeset method
store.applyChangeset(changes, null, '$PhantomId', false);
| Parameter | Type | Description |
|---|---|---|
changes | Object | Changeset to apply to the store, see specification above |
transformFn | function | Optional function used to preprocess a changeset in a different format, should return an object with the format expected by this function (see above) |
phantomIdField | String | Field used by the backend when communicating a record being assigned a proper id instead of a phantom id (see above) |
clearChanges | Boolean | Set to |
Applies changes from another store to this store. Useful if cloning records in one store to display in a grid in a popup etc. to reflect back changes.
| Parameter | Type | Description |
|---|---|---|
otherStore | Store |
Commits changes, per default only returns changes and resets tracking.
| Parameter | Type | Description |
|---|---|---|
silent | Boolean | Specify |
Changes, see changes
Insert records into the store.
| Parameter | Type | Description |
|---|---|---|
index | Number | Index to insert at |
records | Model | Model[] | Object | Object[] | Array of records/data or a single record/data to insert to store |
silent | Boolean | Specify |
Inserted records
Loads a page of data from the implemented requestData function.
| Parameter | Type | Description |
|---|---|---|
page | Number | The one based page number to load. |
params | Object | A hash of parameters to append to the request event and requestData call |
A Promise which will be resolved when the request completes
Moves a record, or block of records to another location.
| Parameter | Type | Description |
|---|---|---|
records | Model | Model[] | The record(s) to move. |
beforeRecord | Model | the record to insert the first record(s) before. |
If this store is paged, and is not already at the lastPage then this will load the next page of data.
A promise which is resolved when the request completes and has been processed.
If this store is paged, and is not already at the first page then this will load the previous page of data.
A promise which is resolved when the request completes and has been processed.
Removes a record from this store. Fires a single remove event passing the removed records.
| Parameter | Type | Description |
|---|---|---|
records | String | String[] | Number | Number[] | Model | Model[] | Record/array of records (or record ids) to remove |
silent | Boolean | Specify |
Removed records
Removes all records from the store.
| Parameter | Type | Description |
|---|---|---|
silent | Boolean | Specify |
true unless the action was prevented, in which case it returns false
Reverts all changes in the store (adds removed records back, and removes newly added records).
Iteration
Equivalent to Array.every(). Returns true if every call of the provided function
on each record yields a truthy value.
| Parameter | Type | Description |
|---|---|---|
fn | function | |
fn.record | function | The record to test. |
thisObj | Object | The |
ignoreFilters | Boolean | Pass |
Equivalent to Array.flatMap(). Creates a new array by spreading the results of calling a provided function on every record
| Parameter | Type | Description |
|---|---|---|
fn | function | A function returning an array of items to be spread into the new array, or a single item to include in it |
thisObj | Object | The |
The new array
Iterates over all available records in store. Omits group header and footer records if this store is grouped. Does not request new records when store is configured with lazyLoad.
| Parameter | Type | Description |
|---|---|---|
fn | function | A function that is called for each record. Returning |
fn.record | Model | Current record |
fn.index | Number | Current index |
thisObj | Object |
|
options | Object | Boolean | A boolean for |
options.includeFilteredOutRecords | Boolean |
|
options.includeCollapsedGroupRecords | Boolean |
|
Equivalent to Array.map(). Creates a new array with the results of calling a provided function on every record
| Parameter | Type | Description |
|---|---|---|
fn | function | |
thisObj | Object | The |
Other
Stops this store from firing events until endBatch is called. Multiple calls to beginBatch
stack up, and will require an equal number of endBatch calls to resume events.
Upon call of endBatch, a refresh event is triggered to allow UIs to update themselves based upon the new state of the store.
This is extremely useful when making a large number of changes to a store. It is important not to trigger too many UI updates for performance reasons. Batching the changes ensures that UIs attached to this store are only updated once at the end of the updates.
Ends event suspension started by beginBatch. Multiple calls to beginBatch
stack up, and will require an equal number of endBatch calls to resume events.
Upon call of endBatch, a refresh event with action: batch is triggered to allow UIs to update
themselves based upon the new state of the store.
This is extremely useful when making a large number of changes to a store. It is important not to trigger too many UI updates for performance reasons. Batching the changes ensures that UIs attached to this store are only updated once at the end of the updates.
Creates a new Store instance, or retrieves an existing one.
A Store config object may contain a type property to identify a specific Store subclass to create.
If type is not specified, a base Store instance will be created.
Get a store by passing in the id of an existing store:
// Get a store by id
const store = Store.getStore('myStoreId');
Create a store from an array of data objects:
const store = Store.getStore([
{ id : 1, name : 'Linda', city : 'NY' },
{ id : 2, name : 'Olivia', city : 'Paris' },
...
]);
Create a store from a config object using a type property to identify a specific Store subclass to create:
const store = Store.getStore({
type : 'tree',
modelClass : MyModel,
data : [
{ id : 1, name : 'Linda', city : 'NY' },
{ id : 2, name : 'Olivia', city : 'Paris' },
...
]
});
| Parameter | Type | Description |
|---|---|---|
id | String | Number | StoreConfig | Object[] | The id of the store to retrieve, or an array of objects from which to create the contents of a new Store. |
storeClass | function | The default Store class to instantiate. |
The newly created Store, or an existing Store if id matched an existing Store.
Responds to mutations of the underlying storage Collection
| Parameter | Type | Description |
|---|---|---|
event | Object |
Retrieve the data of all (unfiltered) records as an array of JSON objects.
const store = new Store({
data : [
{ id : 1, name : 'Superman' },
{ id : 2, name : 'Batman' }
]
});
const jsonArray = store.toJSON();
//jsonArray:
[{id:1,name:"Superman"},{id:2,name:"Batman"}]
Records
Creates a model instance, used internally when data is set/added. Override this in a subclass to do your own custom conversion from data to record.
| Parameter | Type | Description |
|---|---|---|
data | Object | Json data |
skipExpose | Boolean | Supply true when batch setting to not expose properties multiple times |
Get the record at the specified index.
| Parameter | Type | Description |
|---|---|---|
index | Number | Index for the record |
Record at the specified index
Get a locally available record by id. Find the record even if filtered out, part of collapsed group or collapsed node
| Parameter | Type | Description |
|---|---|---|
id | Model | String | Number | Id of record to return. |
A record with the specified id
Get a record by internalId.
| Parameter | Type | Description |
|---|---|---|
internalId | Number | The internalId of the record to return |
A record with the specified internalId
Counts the number of records in the store. Allows passing an options object to control which records are counted. For example:
store.getCount({ filteredOut : true });
store.getCount({ headersFooters : true, collapsed : true });
Consider the following dataset loaded into a Store:
[
{ id : 1, name : 'Linda', city : 'NY' },
{ id : 2, name : 'Olivia', city : 'NY' },
{ id : 3, name : 'John', city : 'Stockholm' }
]
No grouping or filtering is applied, thus all records are accessible ("visible"). Passing the different options below would yield the following results:
| Option | Count | Description |
|---|---|---|
filteredOut |
0 | No records are filtered out |
headersFooters |
0 | No group headers have been generated |
collapsed |
0 | No groups are collapsed |
visibleData |
3 | All data records are "visible" |
all |
3 | All options combined |
Grouping by city yields the following records in the Store (pseudocode):
store.group('city');
[
{ name : 'Group NY', groupHeader : true, expanded : true },
{ id : 1, name : 'Linda', city : 'NY' },
{ id : 2, name : 'Olivia', city : 'NY' },
{ name : 'Group Stockholm', groupHeader : true },
{ id : 3, name : 'John', city : 'Stockholm', expanded : true }
]
Passing the different options below would yield the following results:
| Option | Count | Description |
|---|---|---|
filteredOut |
0 | No records are filtered out |
headersFooters |
2 | Group headers have been generated |
collapsed |
0 | No groups are collapsed |
visibleData |
3 | All data records are "visible" |
all |
5 | All options combined |
Collapsing the Stockholm group yields the following records in the Store (pseudocode):
store.collapse(store.getAt(3));
[
{ name : 'Group NY', groupHeader : true, expanded : true },
{ id : 1, name : 'Linda', city : 'NY' },
{ id : 2, name : 'Olivia', city : 'NY' },
{ name : 'Group Stockholm', groupHeader : true, expanded : false }
]
Passing the different options below would yield the following results:
| Option | Count | Description |
|---|---|---|
filteredOut |
0 | No records are filtered out |
headersFooters |
2 | Group headers have been generated |
collapsed |
1 | A group with one record is collapsed |
visibleData |
2 | Not all data records are "visible" |
all |
5 | All options combined |
Applying a filter further affects the counts (pseudocode):
store.filter('name', 'Linda');
[
{ name : 'Group NY', groupHeader : true, expanded : true },
{ id : 1, name : 'Linda', city : 'NY' }
]
Passing the different options below would yield the following results:
| Option | Count | Description |
|---|---|---|
filteredOut |
2 | Records are filtered out |
headersFooters |
2 | Group headers have been generated* |
collapsed |
1 | A group with one record is collapsed |
visibleData |
1 | Not all data records are "visible" |
all |
5 | All options combined |
* Note that also passing filteredOut would include filtered out group headers in the count.
| Parameter | Type | Description |
|---|---|---|
options | Boolean | Object | Count processed (true) or real records (false), or pass an object with options to control the count. Note that the Boolean signature is deprecated and will be removed in a future version. |
options.filteredOut | Boolean | Count records that are filtered out |
options.headersFooters | Boolean | Count generated group headers and footers (not applicable for tree data) |
options.collapsed | Boolean | Count records that are collapsed away, either belonging to a collapsed group, or by belonging to a collapsed branch in a tree |
options.visibleData | Boolean | Count data records that are not filtered out or collapsed away |
options.all | Boolean | Convenience option to count all records (all options as |
Record count
Creates an array of records from this store from the start to the end - 1
| Parameter | Type | Description |
|---|---|---|
start | Number | The index of the first record to return |
end | Number | The index after the last record to return |
The requested records.
Checks if the specified record is contained in the store
| Parameter | Type | Description |
|---|---|---|
recordOrId | Model | String | Number | Record, or |
Returns the index of the specified record/id, or -1 if not found.
| Parameter | Type | Description |
|---|---|---|
recordOrId | Model | String | Number | Record, or |
visibleRecords | Boolean | Pass |
allExceptFilteredOutRecords | Boolean | For trees, when true this searches all except filtered out records in the flattened tree, similar to a flat store. |
Index for the record/id, or -1 if not found.
Checks if a record is available, in the sense that it is not filtered out, hidden in a collapsed group or in a collapsed parent node of a tree store.
| Parameter | Type | Description |
|---|---|---|
recordOrId | Model | String | Number | Record to check |
Resumes automatic commits upon store changes. Will trigger commit if the internal counter is 0.
Suspends automatic commits upon store changes. Can be called multiple times (it uses an internal counter).
Search
Finds the first record for which the specified function returns true
| Parameter | Type | Description |
|---|---|---|
fn | function | Comparison function, called with record as parameter |
searchAllRecords | Boolean | True to ignore any applied filters when searching |
Record or undefined if none found
store.find(record => record.color === 'blue');
Find occurrences of the specified value in the specified field on all locally available records in the store
| Parameter | Type | Description |
|---|---|---|
field | String | The record field to search in |
value | * | Value to search for |
distinct | Boolean | True to only return distinct matches, no duplicates |
searchAllRecords | Boolean | True to ignore any applied filters when searching |
Array of hits, in the format { index: x, data: record }
Finds the first record for which the specified field has the specified value
| Parameter | Type | Description |
|---|---|---|
fieldName | String | Field name |
value | * | Value to find |
searchAllRecords | Boolean | True to ignore any applied filters when searching |
Record or undefined if none found
Searches the Store records using the passed function.
| Parameter | Type | Description |
|---|---|---|
fn | function | A function that is called for each record. Return true to indicate a match |
searchAllRecords | Boolean | True to ignore any applied filters when searching |
An array of the matching Records
Find all hits matching the specified input.
const store = new Store({
fields : ['name', 'kind'],
data : [
{ id : 1, name : 'Batman', kind : 'hero' },
{ id : 2, name : 'Batkid', kind : 'hero' },
{ id : 3, name : 'Joker', kind : 'villain' },
{ id : 4, name : 'Penguin', kind : 'villain' }
]
});
store.search('villain'); // [{ index : 2, data : joker-record }, { index : 3, data : penguin-record }]
| Parameter | Type | Description |
|---|---|---|
text | String | Value to search for |
fields | String[] | Fields to search value in, searches in all defined fields if not specified |
formatters | function()[] | An array of field formatting functions to format the found value |
searchAllRecords | Boolean | True to ignore any applied filters when searching |
Array of hits, in the format { index: x, data: record }
Returns true if the supplied function returns true for any record in the store
| Parameter | Type | Description |
|---|---|---|
fn | function | A function that should return true to indicate a match |
searchAllRecords | Boolean | True to ignore any applied filters when searching |
store.some(record => record.age > 95); // true if any record has age > 95
Sort, group & filter
Adds a single filter to the filters collection. By default, filters are reevaluated and a Store change event fired.
If the silent parameter is passed as true, multiple filters can be added without causing data changes.
When the filters are as required, call filter with no parameters to apply the filters to the store.
| Parameter | Type | Description |
|---|---|---|
newFilter | CollectionFilterConfig | function | A filter config, or a function to use for filtering. |
silent | Boolean | Pass |
If filterParamName is set on store, this method
returns Collection filter inside a Promise which is resolved after data is loaded from remote server, otherwise it returns null
Add a sorting level (a sorter).
| Parameter | Type | Description |
|---|---|---|
field | String | Sorter[] | Sorter | function | Field to sort by. Can also be an array of sorters, or a sorting function, or a sorter config. |
ascending | Boolean | Sort order (used only if field specified as string) |
If sortParamName is set on store, this method returns Promise
which is resolved after data is loaded from remote server, otherwise it returns null
Removes all filters from the store. Filters that are marked as internal will not be removed.
| Parameter | Type | Description |
|---|---|---|
silent | Boolean | Pass |
If filterParamName is set on store, this method returns Promise
which is resolved after data is loaded from remote server, otherwise it returns null
Removes all groupers, turning store grouping off.
If sortParamName is set on store, this method returns Promise
which is resolved after data is loaded from remote server, otherwise it returns null
Removes all sorters, turning store sorting off.
If sortParamName is set on store, this method returns Promise
which is resolved after data is loaded from remote server, otherwise it returns null
Creates a function used with Array#sort when sorting the store. Override to use your own custom sorting logic.
| Parameter | Type | Description |
|---|---|---|
sorters | Sorter[] | An array of sorter config objects |
Filters the store by adding the specified filter(s) to the existing filters collection applied to this Store. If a filter has an id specified, or a property specified, it will search for corresponding filter(s) in the existing filters first and replace it with a new filter. It will not remove other filters applied to the store!
To add a new filter:
// Filter using simple object
store.filter({
property : 'age',
operator : '>',
value : 90
});
// Filter using function
store.filter(r => r.age < 90);
// Filter using a named filter as a function
store.filter({
id : 'my-filter',
filterBy : record => record.score > 10
});
To remove a specific filter, but keep other filters applied
// Remove by filter `id` or `property`. Filter `id` defaults to the `property-operator` value.
store.removeFilter('age');
store.removeFilter('my-filter');
To replace all existing filters with a new filter
// Remove all filters and filter using simple object
store.filter({
filters : {
property : 'age',
operator : '<',
value : 90
},
replace : true
});
// Remove all filters and filter using function
store.filter({
filters : r => r.age > 90,
replace : true
});
// Remove all filters and filter using a named filter as a function
store.filter({
filters : {
id : 'my-filter',
filterBy : record => record.score > 10
},
replace : true
});
Basically filters replacing is an equivalent of having two sequenced calls: clearFilters and filter.
Call without arguments to reapply filters.
// Re-filter the store
store.filter();
| Parameter | Type | Description |
|---|---|---|
newFilters | Object | CollectionFilterConfig | CollectionFilterConfig[] | function | A filter config,
or an array of filter configs,
or a function to use for filtering,
or a special object like: |
newFilters.replace | Boolean | A flag, indicating whether or not the previous filters should be removed. |
newFilters.silent | Boolean | Set as true to not fire events. UI will not be informed about the changes. |
newFilters.filters | CollectionFilterConfig | CollectionFilterConfig[] | function | If |
If filterParamName is set on store, this method returns Promise which is resolved after data is loaded from remote server, otherwise it returns null value
Adds a function used to filter the store. Alias for calling filter(fn). Return true from the function to
include record in filtered set
store.filterBy(record => record.age > 25 && record.name.startsWith('A'));
| Parameter | Type | Description |
|---|---|---|
fn | function | Function used to test records |
If filterParamName is set on store, this method returns Promise
which is resolved after data is loaded from remote server, otherwise it returns null
Returns all records in the group with specified groupValue.
| Parameter | Type | Description |
|---|---|---|
groupValue | * |
Records in specified group or null if store not grouped
Group records, either by replacing current sorters or by adding to them.
A grouper can specify a custom sorting function which will be called with arguments (recordA, recordB).
Works in the same way as a standard array sorter, except that returning null triggers the stores
normal sorting routine. Grouped store must always be sorted by the same field.
To clear groupers and stop grouping, use clearGroupers method.
// simple grouper
store.group('city');
// grouper as object, descending order
store.group({ field : 'city', ascending : false });
// using custom sorting function
store.group({
field : 'city',
fn : (recordA, recordB) => {
// apply custom logic, for example:
return recordA.city.length < recordB.city.length ? -1 : 1;
}
});
// Stop grouping
store.clearGroupers();
| Parameter | Type | Description |
|---|---|---|
field | String | Object | Field to group by.
Can also be a config containing a field to group by and a custom sorting function called |
field.field | String | Field to group by |
field.fn | function | Custom sorting function |
field.ascending | Boolean | Sort order of the group titles |
ascending | Boolean | Sort order of the group titles |
add | Boolean | Add a grouper (true) or use only this grouper (false) |
performSort | Boolean | Trigger sort directly, which does the actual grouping |
silent | Boolean | Set as true to not fire events |
If sortParamName is set on store, this method returns Promise
which is resolved after data is loaded from remote server, otherwise it returns null
Check if a record belongs to a certain group (only for the first grouping level)
| Parameter | Type | Description |
|---|---|---|
record | Model | The Record |
groupValue | * | The group value |
True if the record belongs to the group, otherwise false
Removes the passed filter, or the filter by the passed ID from the filters collection. By default, filters are reevaluated and a Store change event fired.
If the silent parameter is passed as true, multiple filters can be removed without causing data changes.
When the filters are as required, call filter with no parameters to apply the filters to the store.
// Only view top priority events
myEventStore.filter({
id : 'priorityFilter',
property : 'priority',
value : 1,
operator : '='
});
// That individual filter can be removed like this
myEventStore.removeFilter('priorityFilter');
// Add named filter as a function
store.filter({
id : 'my filter',
filterBy : record => record.score > 10
});
// Remove named filter function
store.removeFilter('my filter');
| Parameter | Type | Description |
|---|---|---|
idOrInstance | String | CollectionFilter | Filter to remove, or ID of the filter to remove. By default, filters are reevaluated and a change event fired. |
silent | Boolean | Pass |
If filterParamName is set on store, this method
returns Collection filter inside a Promise which is resolved after data is loaded from remote server, otherwise it returns null
Remove a sorting level (a sorter)
| Parameter | Type | Description |
|---|---|---|
field | String | function | Stop sorting by this field (or sorter function) |
If sortParamName is set on store, this method returns Promise
which is resolved after data is loaded from remote server, otherwise it returns null
Set groupers.
| Parameter | Type | Description |
|---|---|---|
groupers | Grouper[] | Array of groupers to apply to store |
If sortParamName is set on store, this method returns
Promise which is resolved after data is loaded from remote server, otherwise it returns null
Sort records, either by replacing current sorters or by adding to them.
A sorter can specify a custom sorting function which will be called with arguments (recordA, recordB).
Works in the same way as a standard array sorter, except that returning null triggers the stores
normal sorting routine.
// single sorter
store.sort('age');
// single sorter as object, descending order
store.sort({ field : 'age', ascending : false });
// multiple sorters
store.sort(['age', 'name']);
// using custom sorting function
store.sort((recordA, recordB) => {
// apply custom logic, for example:
return recordA.name.length < recordB.name.length ? -1 : 1;
});
// using locale specific sort (slow)
store.sort({ field : 'name', useLocaleSort : 'sv-SE' });
| Parameter | Type | Description |
|---|---|---|
field | String | Sorter[] | Sorter | function | Field to sort by. Can also be an array of sorter config objects, or a sorting function, or a sorter config. |
ascending | Boolean | Sort order.
Applicable when the |
add | Boolean | If |
silent | Boolean | Set as true to not fire events. UI will not be informed about the changes. |
If sortParamName is set on store, this method returns Promise
which is resolved after data is loaded from remote server, otherwise it returns null
Sum
Returns the average value for the specified field. Defaults to look through all locally available records in store
| Parameter | Type | Description |
|---|---|---|
field | String | Field to calculate average value for |
records | Model[] | Records to process, uses all records if unspecified |
Returns sum by adding value of specified field for records in the group with the specified groupValue.
| Parameter | Type | Description |
|---|---|---|
groupValue | * | The group to summarize |
field | String | Field to summarize by |
Sum or null if store not grouped
Returns max value for the specified field, can be used with Date or Number values. Defaults to look through all locally available records in store
| Parameter | Type | Description |
|---|---|---|
field | String | Field to find max value for |
records | Model[] | Records to process, uses all records if unspecified |
Returns min value for the specified field, can be used with Date or Number values. Defaults to look through all locally available records in store
| Parameter | Type | Description |
|---|---|---|
field | String | Field to find min value for |
records | Model[] | Records to process, uses all records if unspecified |
Traverse
Finds the next record locally available.
| Parameter | Type | Description |
|---|---|---|
recordOrId | Model | String | Number | Current record or its id |
wrap | Boolean | Wrap at start/end or stop there |
skipSpecialRows | Boolean | True to not return specialRows like group headers |
Next record or null if current is the last one
Finds the previous record locally available.
| Parameter | Type | Description |
|---|---|---|
recordOrId | Model | String | Number | Current record or its id |
wrap | Boolean | Wrap at start/end or stop there |
skipSpecialRows | Boolean | True to not return specialRows like group headers |
Previous record or null if current is the last one
Traverse all tree nodes (only applicable for Tree Store)
| Parameter | Type | Description |
|---|---|---|
fn | function | The function to call on visiting each node. |
topNode | Model | The top node to start the traverse at. |
skipTopNode | Boolean | Pass true to not call |
options | Object | Boolean | A boolean for includeFilteredOutRecords, or detailed options for exclude/include records |
options.includeFilteredOutRecords | Boolean | True to also include filtered out records |
options.includeCollapsedGroupRecords | Boolean | True to also include records from collapsed groups of grouped store |
options.useOrderedTree | Boolean | True to traverse unsorted/unfiltered tree |
Traverse all tree nodes while the passed fn returns true
| Parameter | Type | Description |
|---|---|---|
fn | function | The function to call on visiting each node. Returning |
topNode | Model | The top node to start the traverse at. |
skipTopNode | Boolean | Pass true to not call |
options | Object | An options object to exclude/include records |
options.includeFilteredOutRecords | Boolean | True to also include filtered out records |
options.includeCollapsedGroupRecords | Boolean | True to also include records from collapsed groups of grouped store |
Tree
Returns the children of the passed branch node which this store owns. By default, this
is the entire children array.
If this store isChained, then this returns only the subset of children which are filtered into this store by the chainedFilterFn.
| Parameter | Type | Description |
|---|---|---|
parent | Model | The node to return the children of. |
Increase the indentation level of one or more nodes in the tree
| Parameter | Type | Description |
|---|---|---|
nodes | Model | Model[] | The nodes to indent. |
Loads children for a parent node that uses load on demand (when expanding it). Base implementation does nothing,
either use AjaxStore which implements it, create your own subclass with an implementation or listen for
toggleNode and insert records when you have them available.
| Parameter | Type | Description |
|---|---|---|
parentRecord | Model |
A Promise which will be resolved if the load succeeds, and rejected if the load is
vetoed by a beforeLoadChildren handler, or if an exception is detected.
The resolved function is passed the event object passed to any event handlers.
The rejected function is passed the exception event if an exception occurred,
or false if the load was vetoed by a beforeLoadChildren handler.
Decrease the indentation level of one or more nodes in the tree
| Parameter | Type | Description |
|---|---|---|
nodes | Model | Model[] | The nodes to outdent. |
Collapse an expanded record or expand a collapsed. Optionally forcing a certain state.
| Parameter | Type | Description |
|---|---|---|
idOrRecord | String | Number | Model | Record (the record itself) or id of a record to toggle |
collapse | Boolean | Force collapse (true) or expand (false) |
Values
Returns an array of distinct values from all locally available records for the specified field.
store.getDistinctValues('age'); // Returns an array of the unique age values
| Parameter | Type | Description |
|---|---|---|
field | String | Field to extract values for |
includeFilteredOutRecords | Boolean | True to ignore any applied filters |
includeCounts | Boolean | When |
Array of values
Counts how many times the specified value appears locally in the store
| Parameter | Type | Description |
|---|---|---|
field | String | Field to look in |
value | * | Value to look for |
Found count
Configuration
Events
Events
32
Events
32Fired after adding/inserting record(s). If the record was added to a parent, the isChild flag is set on the
event. If it was inserted, event contains index
// Adding a listener using the "on" method
store.on('add', ({ source, records, allRecords, parent, index, oldIndex, isChild, isExpand, isMove }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
records | Model[] | Added records. In case of tree store, if branch is added, only branch root is returned |
allRecords | Model[] | Flat list of all added records. In case of tree store, if branch is added, all new records are returned, not only branch root |
parent | Model | If due to an appendChild call, this is the parent node added to. |
index | Number | Insertion point in the store's Collection. |
oldIndex | Number | Not used for tree stores. The index of the first record moved. |
isChild | Boolean | Flag which is set to |
isExpand | Boolean | Flag which is set to |
isMove | Object | An object keyed by the ids of the records which were moved from another
position in the store, or from another parent node in the store. The ids of moved records will be
property names with a value |
Fired when a temporary record with the isCreating property set has been confirmed as a part of this store by having its isCreating property cleared.
// Adding a listener using the "on" method
store.on('addConfirmed', ({ source, record }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store. |
record | Model | The record confirmed as added. |
Fired after any remote request has finished whether successfully or unsuccessfully.
// Adding a listener using the "on" method
store.on('afterRequest', ({ exception, action, exceptionType, response, json, params }) => {
});| Parameter | Type | Description |
|---|---|---|
exception | Boolean |
|
action | create | read | update | delete | readPage | Action that has finished, |
exceptionType | network | failure | The type of failure, |
response | Response | The |
json | Object | The decoded response object if there was no |
params | Object | An object containing key/value pairs that were passed on the request query string |
Fired before records are added to this store by the add or insert. In a tree
store, also fired by appendChild and
insertChild. The add or insert may be vetoed by returning false
from a handler.
// Adding a listener using the "on" method
store.on('beforeAdd', ({ source, records, parent }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
records | Model[] | The records which are to be added |
parent | Model | The parent node when using a tree store |
Fired before committing changes. Return false from handler to abort commit
// Adding a listener using the "on" method
store.on('beforeCommit', ({ source, changes }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
changes | Object | Modification data |
Fired before filtering
// Adding a listener using the "on" method
store.on('beforeFilter', ({ source, filters }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
filters | Collection | Filters to be applied to this Store |
Fired before nodes in the tree are indented. Return false from a listener to prevent the indent.
// Adding a listener using the "on" method
store.on('beforeIndent', ({ source, records }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | The |
records | Model[] | The nodes to indent. |
When the store is paged, this is fired before loading a page and is cancelable
// Adding a listener using the "on" method
store.on('beforeLoadPage', ({ source, action, url, params }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
action | String | (AjaxStore only) The read action being performed: |
url | String | (AjaxStore only) The URL to which the HTTP request will be sent. This property may be mutated in an event handler without changing the base readUrl configured for this Store. |
params | Object | An object containing property/name pairs which are the parameters. This may be mutated to affect the parameters used in the request. |
Fired before nodes in the tree are outdented. Return false from a listener to prevent the outdent.
// Adding a listener using the "on" method
store.on('beforeOutdent', ({ source, records }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This store |
records | Model[] | Nodes to be outdented |
Fired before records are removed from this store by the remove or removeAll.
Also fired when removing a child record in a tree store using removeChild.
The remove may be vetoed by returning false from a handler.
// Adding a listener using the "on" method
store.on('beforeRemove', ({ source, records, parent, isMove, removingAll }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
records | Model[] | The records which are to be removed. |
parent | Model | The record from which children are being removed when using a tree store. Only provided when removing a single node. |
isMove | Boolean | This flag is |
removingAll | Boolean | This flag is |
Fired before any remote request is initiated.
// Adding a listener using the "on" method
store.on('beforeRequest', ({ source, url, params, body, action }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
url | String | The URL to which the HTTP request will be sent. This property may be mutated in an event handler without changing the base urls configured for this Store. |
params | Object | An object containing key/value pairs that are passed on the request query string |
body | Object | The body of the request to be posted to the server. |
action | create | read | update | delete | readPage | Action that is making the request, |
Fired before sorting
// Adding a listener using the "on" method
store.on('beforeSort', ({ source, sorters, records }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
sorters | Sorter[] | Sorter configs |
records | Model[] | Records to sort |
Fired before record is modified in this store.
Modification may be vetoed by returning false from a handler.
// Adding a listener using the "on" method
store.on('beforeUpdate', ({ source, record, changes }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
record | Model | Modified record |
changes | Object | Modification data |
Data in the store was changed. This is a catch-all event which is fired for all changes which take place to the store's data.
This includes mutation of individual records, adding and removal of records, as well as setting a new data payload using the data property, sorting, filtering, and calling removeAll.
Simple databound widgets may use to the change event to refresh their UI without having to add multiple
listeners to the update, add,
remove, refresh and
removeAll events.
A more complex databound widget such as a grid may use the more granular events to perform less
destructive updates more appropriate to each type of change. The properties will depend upon the value of the
action property.
// Adding a listener using the "on" method
store.on('change', ({ source, action, record, records, changes }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store. |
action | remove | removeAll | add | clearchanges | filter | update | dataset | replace | Name of action which triggered the change. May be one of the options listed above |
record | Model | Changed record, for actions that affects exactly one record ( |
records | Model[] | Changed records, passed for all actions except |
changes | Object | Passed for the |
Fired after committing changes
// Adding a listener using the "on" method
store.on('commit', ({ source, changes }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
changes | Object | Modification data |
Fired after applying filters to the store
// Adding a listener using the "on" method
store.on('filter', ({ source, filters, removed, added, records }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
filters | Collection | Filters used by this Store |
removed | Model[] | The records which were filtered out by the action. |
added | Model[] | The records which were filtered back in by the action. |
records | Model[] | Filtered records |
Fired when grouping changes
// Adding a listener using the "on" method
store.on('group', ({ source, groupers, records }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
groupers | Grouper[] | Applied groupers |
records | Model[] | Grouped records |
Fired when the id of a record has changed
// Adding a listener using the "on" method
store.on('idChange', ({ source, record, oldValue, value }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
record | Model | Modified record |
oldValue | String | Number | Old id |
value | String | Number | New id |
Fired after tasks in the tree are indented
// Adding a listener using the "on" method
store.on('indent', ({ source, records }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | The store |
records | Model[] | Nodes that were indented |
When the store is paged, this is fired when a page is loaded.
// Adding a listener using the "on" method
store.on('loadPage', ({ source, params }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
params | Object | An object containing property/name pairs which are the parameters. This may be mutated to affect the parameters used in the request. |
Fired when a block of records has been moved within this Store
// Adding a listener using the "on" method
store.on('move', ({ source, records, from, to, newParent, oldParents }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store move API now accepts an array of records to move). |
records | Model[] | The moved records. |
from | Number | The index from which the record was removed (applicable only for flat store). |
to | Number | The index at which the record was inserted (applicable only for flat store). |
newParent | Model | The new parent record for the dragged records (applicable only for tree stores) |
oldParents | Model[] | The old parent records for the dragged records (applicable only for move operations in tree stores) |
Fired after tasks in the tree are outdented
// Adding a listener using the "on" method
store.on('outdent', ({ source, records }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | The store |
records | Model[] | Nodes that were outdented |
Data in the store has completely changed, such as by a filter, or sort or load operation.
// Adding a listener using the "on" method
store.on('refresh', ({ source, batch, action }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store. |
batch | Boolean | Flag set to |
action | dataset | sort | clearchanges | filter | create | update | delete | group | Name of action which triggered the change. May be one of the options listed above. |
Fired when one or more records are removed
// Adding a listener using the "on" method
store.on('remove', ({ source, records, allRecords, parent, index, isChild, isCollapse, isMove }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
records | Model[] | Array of removed records. In case of tree store, if branch is removed, only branch root is returned |
allRecords | Model[] | Flat array of all removed records. In case of tree store, if branch is removed, all removed records are returned, not only branch root |
parent | Model | If due to a removeChild call, this is the parent node removed from. Only applicable when removing a single tree node. |
index | Number | Visible index at which record was removed. In case the record was removed from a collapsed branch, -1 is returned. For tree store, this is only provided when removing a single node. |
isChild | Boolean | Flag which is set to |
isCollapse | Boolean | Flag which is set to |
isMove | Boolean | Passed as |
Fired after removing all records
// Adding a listener using the "on" method
store.on('removeAll', ({ source }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
This event only fires in a non-AjaxStore, configured with remoteSort, remoteFilter or remotePaging, when the Store requests more or new data.
The event will contain same params as described in the requestData function. This event can be listened to if you want to receive notifications about the Store's data requests, but not directly want to return the requested data. For example, when you got the Store's data bound to a data source with the help of an external library/framegrunt docswork.
// Adding a listener using the "on" method
store.on('requestData', ({ }) => {
});Fired when the root node is set
// Adding a listener using the "on" method
store.on('rootChange', ({ source, oldRoot, rootNode }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
oldRoot | Model | The old root node. |
rootNode | Model | The new root node. |
Fired after sorting
// Adding a listener using the "on" method
store.on('sort', ({ source, sorters, records }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
sorters | Sorter[] | Sorter configs |
records | Model[] | Sorted records |
Fired when a record is modified
// Adding a listener using the "on" method
store.on('update', ({ source, record, changes }) => {
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
record | Model | Modified record |
changes | Object | Modification data |
Event handlers
32
Event handlers
32Called after adding/inserting record(s). If the record was added to a parent, the isChild flag is set on the
event. If it was inserted, event contains index
new Store({
onAdd({ source, records, allRecords, parent, index, oldIndex, isChild, isExpand, isMove }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
records | Model[] | Added records. In case of tree store, if branch is added, only branch root is returned |
allRecords | Model[] | Flat list of all added records. In case of tree store, if branch is added, all new records are returned, not only branch root |
parent | Model | If due to an appendChild call, this is the parent node added to. |
index | Number | Insertion point in the store's Collection. |
oldIndex | Number | Not used for tree stores. The index of the first record moved. |
isChild | Boolean | Flag which is set to |
isExpand | Boolean | Flag which is set to |
isMove | Object | An object keyed by the ids of the records which were moved from another
position in the store, or from another parent node in the store. The ids of moved records will be
property names with a value |
Called when a temporary record with the isCreating property set has been confirmed as a part of this store by having its isCreating property cleared.
new Store({
onAddConfirmed({ source, record }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store. |
record | Model | The record confirmed as added. |
Called after any remote request has finished whether successfully or unsuccessfully.
new Store({
onAfterRequest({ exception, action, exceptionType, response, json, params }) {
}
});| Parameter | Type | Description |
|---|---|---|
exception | Boolean |
|
action | create | read | update | delete | readPage | Action that has finished, |
exceptionType | network | failure | The type of failure, |
response | Response | The |
json | Object | The decoded response object if there was no |
params | Object | An object containing key/value pairs that were passed on the request query string |
Called before records are added to this store by the add or insert. In a tree
store, also called by appendChild and
insertChild. The add or insert may be vetoed by returning false
from a handler.
new Store({
onBeforeAdd({ source, records, parent }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
records | Model[] | The records which are to be added |
parent | Model | The parent node when using a tree store |
Called before committing changes. Return false from handler to abort commit
new Store({
onBeforeCommit({ source, changes }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
changes | Object | Modification data |
Called before filtering
new Store({
onBeforeFilter({ source, filters }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
filters | Collection | Filters to be applied to this Store |
Called before nodes in the tree are indented. Return false from a listener to prevent the indent.
new Store({
onBeforeIndent({ source, records }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | The |
records | Model[] | The nodes to indent. |
When the store is paged, this is called before loading a page and is cancelable
new Store({
onBeforeLoadPage({ source, action, url, params }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
action | String | (AjaxStore only) The read action being performed: |
url | String | (AjaxStore only) The URL to which the HTTP request will be sent. This property may be mutated in an event handler without changing the base readUrl configured for this Store. |
params | Object | An object containing property/name pairs which are the parameters. This may be mutated to affect the parameters used in the request. |
Called before nodes in the tree are outdented. Return false from a listener to prevent the outdent.
new Store({
onBeforeOutdent({ source, records }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This store |
records | Model[] | Nodes to be outdented |
Called before records are removed from this store by the remove or removeAll.
Also called when removing a child record in a tree store using removeChild.
The remove may be vetoed by returning false from a handler.
new Store({
onBeforeRemove({ source, records, parent, isMove, removingAll }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
records | Model[] | The records which are to be removed. |
parent | Model | The record from which children are being removed when using a tree store. Only provided when removing a single node. |
isMove | Boolean | This flag is |
removingAll | Boolean | This flag is |
Called before any remote request is initiated.
new Store({
onBeforeRequest({ source, url, params, body, action }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
url | String | The URL to which the HTTP request will be sent. This property may be mutated in an event handler without changing the base urls configured for this Store. |
params | Object | An object containing key/value pairs that are passed on the request query string |
body | Object | The body of the request to be posted to the server. |
action | create | read | update | delete | readPage | Action that is making the request, |
Called before sorting
new Store({
onBeforeSort({ source, sorters, records }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
sorters | Sorter[] | Sorter configs |
records | Model[] | Records to sort |
Called before record is modified in this store.
Modification may be vetoed by returning false from a handler.
new Store({
onBeforeUpdate({ source, record, changes }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
record | Model | Modified record |
changes | Object | Modification data |
Data in the store was changed. This is a catch-all event which is called for all changes which take place to the store's data.
This includes mutation of individual records, adding and removal of records, as well as setting a new data payload using the data property, sorting, filtering, and calling removeAll.
Simple databound widgets may use to the change event to refresh their UI without having to add multiple
listeners to the update, add,
remove, refresh and
removeAll events.
A more complex databound widget such as a grid may use the more granular events to perform less
destructive updates more appropriate to each type of change. The properties will depend upon the value of the
action property.
new Store({
onChange({ source, action, record, records, changes }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store. |
action | remove | removeAll | add | clearchanges | filter | update | dataset | replace | Name of action which triggered the change. May be one of the options listed above |
record | Model | Changed record, for actions that affects exactly one record ( |
records | Model[] | Changed records, passed for all actions except |
changes | Object | Passed for the |
Called after committing changes
new Store({
onCommit({ source, changes }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
changes | Object | Modification data |
Called after applying filters to the store
new Store({
onFilter({ source, filters, removed, added, records }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
filters | Collection | Filters used by this Store |
removed | Model[] | The records which were filtered out by the action. |
added | Model[] | The records which were filtered back in by the action. |
records | Model[] | Filtered records |
Called when grouping changes
new Store({
onGroup({ source, groupers, records }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
groupers | Grouper[] | Applied groupers |
records | Model[] | Grouped records |
Called when the id of a record has changed
new Store({
onIdChange({ source, record, oldValue, value }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
record | Model | Modified record |
oldValue | String | Number | Old id |
value | String | Number | New id |
Called after tasks in the tree are indented
new Store({
onIndent({ source, records }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | The store |
records | Model[] | Nodes that were indented |
When the store is paged, this is called when a page is loaded.
new Store({
onLoadPage({ source, params }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
params | Object | An object containing property/name pairs which are the parameters. This may be mutated to affect the parameters used in the request. |
Called when a block of records has been moved within this Store
new Store({
onMove({ source, records, from, to, newParent, oldParents }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store move API now accepts an array of records to move). |
records | Model[] | The moved records. |
from | Number | The index from which the record was removed (applicable only for flat store). |
to | Number | The index at which the record was inserted (applicable only for flat store). |
newParent | Model | The new parent record for the dragged records (applicable only for tree stores) |
oldParents | Model[] | The old parent records for the dragged records (applicable only for move operations in tree stores) |
Called after tasks in the tree are outdented
new Store({
onOutdent({ source, records }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | The store |
records | Model[] | Nodes that were outdented |
Data in the store has completely changed, such as by a filter, or sort or load operation.
new Store({
onRefresh({ source, batch, action }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store. |
batch | Boolean | Flag set to |
action | dataset | sort | clearchanges | filter | create | update | delete | group | Name of action which triggered the change. May be one of the options listed above. |
Called when one or more records are removed
new Store({
onRemove({ source, records, allRecords, parent, index, isChild, isCollapse, isMove }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
records | Model[] | Array of removed records. In case of tree store, if branch is removed, only branch root is returned |
allRecords | Model[] | Flat array of all removed records. In case of tree store, if branch is removed, all removed records are returned, not only branch root |
parent | Model | If due to a removeChild call, this is the parent node removed from. Only applicable when removing a single tree node. |
index | Number | Visible index at which record was removed. In case the record was removed from a collapsed branch, -1 is returned. For tree store, this is only provided when removing a single node. |
isChild | Boolean | Flag which is set to |
isCollapse | Boolean | Flag which is set to |
isMove | Boolean | Passed as |
Called after removing all records
new Store({
onRemoveAll({ source }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
This event only called in a non-AjaxStore, configured with remoteSort, remoteFilter or remotePaging, when the Store requests more or new data.
The event will contain same params as described in the requestData function. This event can be listened to if you want to receive notifications about the Store's data requests, but not directly want to return the requested data. For example, when you got the Store's data bound to a data source with the help of an external library/framegrunt docswork.
new Store({
onRequestData({ }) {
}
});Called when the root node is set
new Store({
onRootChange({ source, oldRoot, rootNode }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
oldRoot | Model | The old root node. |
rootNode | Model | The new root node. |
Called after sorting
new Store({
onSort({ source, sorters, records }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
sorters | Sorter[] | Sorter configs |
records | Model[] | Sorted records |
Called when a record is modified
new Store({
onUpdate({ source, record, changes }) {
}
});| Parameter | Type | Description |
|---|---|---|
source | Store | This Store |
record | Model | Modified record |
changes | Object | Modification data |
Typedefs
8
Typedefs
8An object containing details about the received data used for lazy and paged loading
| Parameter | Type | Description |
|---|---|---|
data | Object[] | The data being received |
total | Number | The total number of records available |
An immutable object representing a store grouper.
| Parameter | Type | Description |
|---|---|---|
field | String | Field name |
ascending | Boolean |
|
An object containing details about the requested data
| Parameter | Type | Description |
|---|---|---|
startIndex | Number | The index of the first record being requested |
count | Number | The number of records being requested |
sorters | Sorter[] | If remoteSort is active, this will contain a number of sorter objects |
filters | CollectionFilterConfig[] | If remoteFilter is active, this will contain a number of filters objects |
startDate | Date | The startDate of the requested date range (only if applicable) |
endDate | Date | The endDate of the requested date range (only if applicable) |
parentId | String | Number | The parentId for which to load children (only if tree store) |
resourceIds | String[] | Number[] | If this store is part of a Scheduler or a Gantt, and is a store
dependent on the |
An object containing details about the requested data
| Parameter | Type | Description |
|---|---|---|
page | Number | The page number being requested |
pageSize | Number | The number of records being requested |
sorters | Sorter[] | If remoteSort is active, this will contain a number of sorter objects |
filters | CollectionFilterConfig[] | If remoteFilter is active, this will contain a number |
An immutable object representing a store sorter.
| Parameter | Type | Description |
|---|---|---|
field | String | Field name |
fn | function | A custom sorting function, to be used instead of the "field" |
ascending | Boolean |
|
Format returned by Store#findByField().
| Parameter | Type | Description |
|---|---|---|
index | Number | Index of the record in the store |
data | Model | The record |
Options available when supplying a config object to the syncDataOnLoad config.
| Parameter | Type | Description |
|---|---|---|
keepMissingValues | Boolean | How to handle values for missing fields, see syncDataOnLoad |
threshold | String | Number | Threshold above which events are batched, see syncDataOnLoad |