Store
A Store
is the main location for keeping structured state and tabular data.
Create a Store
easily with the createStore
function. From there, you can set and get data, add listeners for when the data changes, set a Schema
, and so on.
A Store
has a simple hierarchical structure:
- The
Store
contains a number ofTable
objects. - Each
Table
contains a number ofRow
objects. - Each
Row
contains a number ofCell
objects.
A Cell
is a string, boolean, or number value.
The members of each level of this hierarchy are identified with a unique Id
(which is a string). In other words you can naively think of a Store
as a three-level-deep JavaScript object, keyed with strings:
{ // Store
"table1": { // Table
"row1": { // Row
"cell1": "one", // Cell (string)
"cell2": true, // Cell (boolean)
"cell3": 3, // Cell (number)
...
},
...
},
...
}
In its default form, a Store
has no sense of a structured schema, so, as long as they are unique within their own parent, the Id
keys can each be any string you want. However, you can optionally specify a Schema
for a Store
, which then usefully constrains the Table
and Cell
Ids
(and Cell
values) you can use.
Setting and getting data
Every part of the Store
can be accessed with getter methods. When you retrieve data from the Store
, you are receiving a copy - rather than a reference - of it. This means that manipulating the data in the Store
must be performed with the equivalent setter and deleter methods.
To benefit from the reactive behavior of the Store
, you can also subscribe to changes on any part of it with 'listeners'. Registering a listener returns a listener Id
(that you can use later to remove it with the delListener method), and it will then be called every time there is a change within the part of the hierarchy you're listening to.
This table shows the main ways you can set, get, and listen to, different types of data in a Store
:
Additionally, there are two extra methods to manipulate Row
objects. The addRow
method is like the setRow
method but automatically assigns it a new unique Id
. And the setPartialRow
method lets you update multiple Cell
values in a Row
without affecting the others.
You can listen to attempts to write invalid data to a Cell
with the addInvalidCellListener
method.
The transaction
method is used to wrap multiple changes to the Store
so that the relevant listeners only fire once.
The setJson
method and the getJson
method allow you to work with a JSON-encoded representation of the entire Store
, which is useful for persisting it.
Finally, the callListener
method provides a way for you to manually provoke a listener to be called, even if the underlying data hasn't changed. This is useful when you are using mutator listeners to guarantee that data conforms to programmatic conditions, and those conditions change such that you need to update the Store
in bulk.
Read more about setting and changing data in The Basics guides, and about listeners in the Listening to Stores guide.
Creating a Schema
You can set a Schema
on a Store
when you create it with createStore
function, or at a later stage with the setSchema
method. A Schema
constrains the Table
Ids
the Store
can have, and the types of Cell
data in each Table
. Each Cell
requires its type to be specified, and can also take a default value for when it's not specified.
You can also get a serialization of the Schema
out of the Store
with the getSchemaJson
method, and remove the Schema
altogether with the delSchema
method.
Read more about schemas in the Using Schemas guide.
Convenience methods
There are a few additional helper methods to make it easier to work with a Store
. There are methods for easily checking the existence of a Table
, Row
, or Cell
, and iterators that let you act on the children of a common parent:
Checking existence | Iterator | |
---|---|---|
Table | hasTable | forEachTable |
Row | hasRow | forEachRow |
Cell | hasCell | forEachCell |
Finally, the getListenerStats method describes the current state of the Store
's listeners for debugging purposes.
Example
This example shows a very simple lifecycle of a Store
: from creation, to adding and getting some data, and then registering and removing a listener.
const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
console.log(store.getRow('pets', 'fido'));
// -> {species: 'dog'}
store.setCell('pets', 'fido', 'color', 'brown');
console.log(store.getCell('pets', 'fido', 'color'));
// -> 'brown'
const listenerId = store.addTableListener('pets', () => {
console.log('changed');
});
store.setCell('pets', 'fido', 'sold', false);
// -> 'changed'
store.delListener(listenerId);
See also
The Basics guides
Using Schemas guides
Hello World demos
Todo App demos
Getter methods
This is the collection of getter methods within the Store
interface. There are 13 getter methods in total.
Setter methods
This is the collection of setter methods within the Store
interface. There are 8 setter methods in total.
Listener methods
This is the collection of listener methods within the Store
interface. There are 12 listener methods in total.
Iterator methods
This is the collection of iterator methods within the Store
interface. There are only three iterator methods, forEachTable
, forEachRow
, and forEachCell
.
Transaction methods
This is the collection of transaction methods within the Store
interface. There are only three transaction methods, finishTransaction
, startTransaction
, and transaction
.
Deleter methods
This is the collection of deleter methods within the Store
interface. There are 5 deleter methods in total.
Development methods
This is the collection of development methods within the Store
interface. There is only one method, getListenerStats
.