constructor/store
Adds support for keeping references to active lists and instances. Prevents different copies of an instance from being used by the application at once. Allows other behaviors to look up instances currently active in the application.
constructorStore( baseConnection )
Overwrites baseConnection
so it contains a store for instances and lists. This behavior:
- extends the hydrateInstance and hydrateList methods to return instances or lists from the store, if available
- overwrites "CRUD" methods to make sure that while requests are pending, new lists and instances have references kept in the store. This prevents duplicated instances from being created during concurrent requests.
- provides methods to add and remove items in the store by counting references
Parameters
- baseConnection
{Object}
:can-connect
connection object that is having theconstructor/store
behavior added on to it. Should already contain a behavior that provides the InstanceInteface (e.g constructor). If theconnect
helper is used to build the connection, the behaviors will automatically be ordered as required.
Returns
{Object}
:
a can-connect
connection containing the method implementations provided by constructor/store
.
Use
The constructor-store
behavior is used to:
- provide a store of instances and lists in use by the client
- prevent multiple instances from being generated for the same id or multiple lists for the same listQuery.
The store provides access to an instance by its id or a list by its listQuery. This is used by other behaviors to lookup instances that should have changes applied. Two examples, when there is a new instance that should be added to a list (real-time) or when newer data is available for a cached instance that is used in the page (fall-through-cache).
Below you can see how constructor-store
's behavior be used to prevent multiple instances from being generated. This
example allows you to create multiple instances of a todoEditor
that loads and edits a todo instance:
You can see in this example that you can edit one todo and the other todos update. This is because each todoEditor
is acting on same instance in memory. When it updates the todo's name here:
var updateData = function(newName) {
todo.name = newName; // update name on todo instance
...
};
The other widgets update because they are bound to the same instance:
todo.on("name", updateElement); // when todo name changes update input element
todosConnection.addInstanceReference(todo); // previous line is a new usage of todo, so increase reference count
Each todoEditor
receives the same instance because it was added to the
connnection.instanceStore by
addInstanceReference. During all instance retrievals, a connection using the
constructor/store
behavior checks the instanceStore for an instance with a
matching id
and return that if it exists. This example always requests id: 5
, so all the todoEditor
s use the
same instance held in the instanceStore.
This widget cleans itself up when it is removed by removing the listener on the todo
instance and
reducing the instance reference count:
todo.off("name", updateElement); // stop listening to todo name change
todosConnection.deleteInstanceReference(todo); // previous line removed a usage of todo, so reduce reference count
This is done to prevent a memory leak produced by keeping instances in the instanceStore
when they are no longer
needed by the application.
Note: a hazard of sharing the same instance is that if new instance data is loaded from the server during on-going editing of the instance, the new server data will replace the data that is edited but not yet saved. This is because whenever data is loaded from the server, it is passed to updatedInstance which updates the shared instance properties with the new server data.