Backbone extension that implements purposes of the Repository pattern, which means the enhancement of the model management and synchronization, so as to provide strong features to build online, offline and hybrid web applications.
The library mainly supports the following features:
- Model register: A Collection (C) keeps models instantiated.
- Sync modes: Sync modes (m) are sync functions to different data sources that are managed by a Repository (R).
- Sync state: A Model (M) keeps changes not synchronized for each sync mode defined.
- Sync operations: A Model (M) runs operations (fetch, save, destroy, pull, push and check) on different sync modes.
- backbone-repository - core library.
- backbone-respository-locally - core library + localStorage support through the Locally plugin.
- Usage
- Reference API
- Building and Testing
- Release History
- License
The extension implements a model caching strategy. By this, a model register in the form of a collection will be responsible for keeping in-memory all instantiated models.
var User = Backbone.Model.extend();
// A static method that returns the collection of users
var userRegister = User.register();
Along with that, a factory method will manage such register and will instantiate or return a model ensuring that it is not instantiated twice according to its identifier attribute. Both model register and factory method will be accessed through a static method of the model.
// Creating instances through the factory method
var user = User.create({id: 1});
var duplicate = User.create({id: 1, name: "Nacho"});
// Ensures a model has been instantiated once.
user === duplicate; // true
// The user has been updated as well.
user.get("name") === "Nacho"; // true
Besides, collections will rely on the factory method to create the instances of the model class associated. So,
var Users = Backbone.Collection.extend({
model: function(attrs, options) {
return User.create(attrs, options);
}
});
A sync mode is responsible to provide logic to access to different data sources. There exists several predefined modes, but you are enable to configure your custom sync mode as well.
For using a mode, you must pass the mode as an option for every single sync operation, whether fetch, update, destroy, pull, push or check.
// E.g. fetching operation using the server mode
user.fetch({
mode: "server"
});
The server mode uses the Backbone's sync function to perform a remote call against a REST API. It is the mode executed by default when using the model manager methods. Both the success and error callbacks are allowed in this mode.
// E.g. saving operation using the server mode
user.save(null, {
mode: "server"
});
The client mode just perform local operations to the model. The success callback is only enabled in this mode.
// E.g. destroying operation using the client mode
user.destroy({
mode: "client"
});
The LocalStorage mode runs the model operations against LocalStorage. Both the success and error callbacks are allowed in this mode. For working, it requires Locally plugin and the "backbone-repository-locally" version of the library.
For using this mode, you must specify an storeName
whether in the model definition or by parameter when saving.
// Specify `storeName` in the model definition.
var User = Backbone.Model.extend({
storeName: "User"
});
var user = User.create({id: 1});
// Specify `storeName` when saving.
user.save(null, {
mode: "localStorage",
storeName: "User"
});
You may also specify an storagePrefix
for all your models when persisting in LocalStorage.
// Specify `storagePrefix`.
Backbone.Repository.storagePrefix = "MyPrefix";
Finally, the LocalStorage key will read as follows: storagePrefix:storeName:[id|localId].
The extension features a way to configure your custom sync modes.
var syncStrategy = function (method, model, options) {
// sync function logic
};
// Registers a new sync mode.
Backbone.Repository.setMode({
mySyncMethod: syncStrategy
});
It is also possible to establish which mode will be selected by default when none selected.
// Defaults a sync mode.
Backbone.Repository.setDefaultMode("mySyncMethod");
The model prototype has been expanded to work up the Repository features intented.
The fetch state means whether the model has been fetched using a sync mode or not. It is possible to pass the sync mode against you wish to check as an option. By default, it will check against the server mode.
user.fetch({
mode: "server",
success: function (model, response, options) {
user.isFetched({
mode: "server"
}); // true
}
});
user.isFetched({
mode: "server"
}); // false
The dirty attributes is a hash that keeps the model attributes that have changed since its last sync for each existing sync mode. The hash will be progressively emptying as attributes are sucessfully synchronized against each sync mode.
For implementing this, the set
method has been altered and configured to handle dirty changes.
// The 'set' method automatically stores dirtied attributes.
user.set({
name: "Nacho"
});
Both dirtiedAttributes
and hasDirtied
methods are possible to pass the sync mode against you wish to check as an option. By default, it will check against the server mode.
user.hasDirtied({
mode: "server"
}); // true
user.dirtiedAttributes({
mode: "server"
}); // outputs {name: "Nacho"}
The dirty handler may be turned off by passing dirty option to set
method.
// The 'set' method won't store dirtied attributes.
user.set({
name: "Nacho"
}, {
dirty: false
});
user.hasDirtied({
mode: "server"
}); // false
The dirty destroy state means whether the model has been destroyed locally or not.
user.destroy({
mode: "client"
});
user.isDirtyDestroyed(); // true
The destroy state means whether the model has been destroyed using a sync mode or not. It is possible to pass the sync mode against you wish to check as an option. By default, it will check against the server mode.
user.destroy({
mode: "server",
success: function (model, response, options) {
user.isDestroyed({
mode: "server"
}); // true
}
});
user.isDestroyed({
mode: "server"
}); // false
The version state is an attribute configured for each model. It is useful to stamp versions on the models when working with serveral data sources, for example a REST server and LocalStorage.
var User = Backbone.Model.extend({
versionAttribute: "version"
});
When calling some operation that uses set
method, you are enabled to check if the version has been updated by passing an option. In case the model is outdated, it will force the fetched state to false
. An event named outdated
is also triggered when the version attribute is changed.
var user = User.create({
version: 1
});
user.isFetched(); // true, lets suppose that the model is fetched
user.set({
version: 2
}, {
version: true // forces to check version status
});
user.isFetched(); // false, the version has changed.
Along with predefined sync operations such as fetch, save and destroy, the extension implements three useful methods: pull, push and check.
By default, all sync operations use the server mode, but it may use another one just by passing the mode as parameter.
Besides, all sync operations has been adapted to be used from Collection.
The pull method performs a read request only if the model has not been fetched before.
var user = User.create({id: 1});
user.isFetched(); // false
// Performs a sync call on its first fetching, such as fetch.
user.pull({
mode: "server",
success: function (model, response, options) {
user.isFetched(); // true
}
});
Once the model has been fetched, the pull
method won't request it again. However, the success
callback will be executed.
user.isFetched(); // true
// It won't request since it was fetched before.
user.pull({
mode: "server"
});
The push method performs a request whether create, update or destroy methods according to the sync status.
// Create example
var user = User.create({
name: "Nacho"
});
// A create request will be emitted.
user.push({
mode: "server"
});
// Update example
user = User.create({
id: 1,
name: "Nacho"
});
// An update request will be emitted.
user.push({
mode: "server"
});
// Destroy example
user.destroy({
mode: "client"
});
// A destroy request will be emitted.
user.push({
mode: "server"
});
The check method is devised to fetch only the model version attribute and check is up to date. This has the sense to be used with remote sync modes. The server mode is configured to accept the checkUrl
, which represent the checking endpoint.
var User = Backbone.Model.extend({
versionAttribute: "version",
checkUrl: "A_CHECKING_ENDPOINT_FOR_MODEL"
});
var user = User.create({
id: 1,
version: 1
});
// Assuming that the user is already fetched
user.isFetched(); // true
user.check({
mode: "server",
success: function (model, response, options) {
// Lets assume a new version is available,
// then the user is about to be fetched again.
user.isFetched(); // false
}
});
This method meant to be useful using through a Collection since you will verify the models all at once.
var Users = Backbone.Collection.extend({
checkUrl: "A_CHECKING_ENDPOINT_FOR_COLLECTION"
});
var user = User.create({id: 1, version: 1});
var user2 = User.create({id: 2, version: 1});
// Assuming that models are already fetched.
user.isFetched(); // true
user2.isFetched(); // true
var users = new Users([user, user2]);
users.check({
mode: "server",
success: function (collection, response, options) {
// Lets assume a new version is only available for the user one,
// then the user one is about to be fetched again.
user.isFetched(); // false
user2.isFetched(); // true
}
});
Returns an array with the name of the available modes.
Returns the sync function of the provided mode.
Available parameters:
- name {String} The mode name.
Registers a new mode by provinding its name and sync function.
Available parameters:
- name {String|Object} The mode name or an object containing the name and sync function.
- fn {Function} The sync function
Returns the default mode.
Establish which mode will be used by default.
Available parameters:
- name {String} The mode name.
Removes the sync mode registered.
Available parameters:
- name {String} The mode name.
Cleans all the sync modes registered.
The prefix used in all storages. Requires Locally extension.
Wheter to use Locally compression by default or not. Requires Locally extension.
Factory method that returns a model instance and ensures only one is gonna be created with same id.
Available parameters:
- attrs {Object} The attributes for the new instance.
- options {Object} The options for the new instance.
Returns a model by its id or cid from the local cache of the model.
Available parameters:
- attrs {Object} An id or cid for looking up.
Returns the collection that represents the local cache of the model.
Resets the local cache of the model.
Returns true
whether this model has been fetched through the sync mode or false
otherwise.
Available parameters:
- options.mode {String} [mode=defaultMode] The sync mode name for checking.
Internal hash containing all attributes that have changed since the last sync for each sync mode.
Retrieve a copy of the attributes that have changed since the last sync.
Available parameters:
- options.mode {String} [mode=defaultMode] The sync mode name.
Returns true
in case the model changed since its last sync, false
otherwise.
Available parameters:
- options.mode {String} [mode=defaultMode] The sync mode name.
Returns true
if this model has been destroyed locally, false
otherwise.
Erases dirtied changes of the model, whether attribute change or model destroy.
Alters set method to provide new options.
Available parameters:
- options.dirty {Boolean} [dirty=true] Whether to handle dirtied changes or not.
- options.version {Boolean} [version=true] Whether to handle version changes or not.
- options.localStorage {Boolean} [localStorage= true] Forces to save the model in LocalStorage. Requires Locally extension.
Returns true
if this model has been destroyed remotely, false
otherwise.
Available parameters:
- options.mode {String} [mode=defaultMode] The sync mode name.
Fetches the model using the sync mode selected if it has not been fetched before.
Available parameters:
- options.mode {String} [mode=defaultMode] The sync mode name.
Pushes the changes performed to the model using the sync mode selected. It may emitt create, update or destroy operations.
Available parameters:
- options.mode {String} [mode=defaultMode] The sync mode name.
- options.patch {Boolean} Use patch request when updating.
The checking endpoint in the server mode.
Fetches version attribute of the model and checks the uptodate status.
Available parameters:
- options.mode {String} [mode=defaultMode] The sync mode name.
- options.checkUrl {String} The checking endpoint in the server mode.
The storage key for persisting the model. Requires Locally extension.
Saves the whole collection using the sync mode. The server mode emitts one request per model.
Available parameters:
- options.mode {String} [mode=defaultMode] The sync mode name.
Destroys the whole collection using the sync mode. The server mode emitts one request per model.
Available parameters:
- options.mode {String} [mode=defaultMode] The sync mode name.
Pulls the whole collection using the sync mode. The server mode may emit urls that take the form of url+ subset of ids for fetching separated by comma.
Available parameters:
- options.mode {String} [mode=defaultMode] The sync mode name.
Pushes the changes of the whole collection using the sync mode. The server mode emitts one request per model.
Available parameters:
- options.mode {String} [mode=defaultMode] The sync mode name.
- options.patch {Boolean} Use patch request when updating.
Checks the whole collection using the sync mode.
Available parameters:
- options.mode {String} [mode=defaultMode] The sync mode name.
- options.checkUrl {String} The checking endpoint in the server mode.
The storage key for persisting the collection. Requires Locally extension.
First install locally all the required development dependencies.
npm install
grunt base
grunt baseLocally
grunt test
Read the CHANGELOG.md file distributed with the project.
Read the LICENSE file distributed with the project.