Still hacking. Come back later. Release coming soon!
Created by Esa-Matti Suuronen, Opinsys Oy
Backbone.SharedCollection is a dead simple way to add automatic synchronization
and persistence to your Backbone.js models. You don't need to do any changes to
your Models. All you need to do is add them to a collection created from
Backbone.SharedCollection
and they will be magically shared between all open
browser instances.
It works by overriding Backbone.sync. The save
method in models and
collections is not used. All changes are automatically saved and synced as
models change. See usage documentation to see how to ignore this temporally.
This commit shows how the stock TODOs example in Backbone.js is changed to use automatic synchronization using Backbone.SharedCollection instead of just localStorage persistence.
This library was originally created in Pahvi Project.
Backbone.SharedCollection uses Node.js and ShareJS to synchronize the Models. So you need a simple Node.js server. Like this one:
var express = require("express");
var sharejs = require("share").server;
var app = express.createServer();
sharejs.attach(app, {
db:{ type: "none" }
});
For persistence options see ShareJS documentation.
In addition to Backbone.js you need also ShareJS and it's dependencies, Socket.io, added to your app:
<!-- Socket.io and ShareJS served directly from Node.js server -->
<script src="/socket.io/socket.io.js"></script>
<script src="/share/share.uncompressed.js"></script>
<script src="/share/json.uncompressed.js"></script>
<!-- Basic Backbone.js dependencies -->
<script src="/vendor/jquery.js"></script>
<script src="/vendor/underscore.js"></script>
<script src="/vendor/backbone.js"></script>
<!-- and finally you can add Backone.SharedCollection -->
<script src="backbone.sharedcollection.js"></script>
For fully working app see examples/todos.
You start by creating instance of SharedCollection with collectionId
.
Collection ID is used to connect different collection instances between the
browsers.
var collection = new Background.SharedCollection([], {
collectionId: "mycollection"
});;
Connect the collection to ShareJS by calling fetch
with a ShareJS document.
If you try to add models to the collection before this they will put into a
queue and are really added right after you call the fetch
method.
sharejs.open('todos', 'json', function(err, doc) {
if (err) throw err;
collection.fetch({
sharejsDoc: doc,
success: initCallback,
error: displayErrorCallback
});
});
You can use the same ShareJS document for multiple collections.
Then you can just start adding models to your collection
function initCallback() {
model = new Backbone.Model;
collection.add(model);
}
Now all set
, destroy
and collection.add
method calls will be propagated
to all other browser instances automatically.
model.set({ foo: "bar" });
model.destroy();
If you need to make an only local change to your model you can pass { local: true }
as options to set
. Remotes won't receive this change.
model.set({ foo: "bar local only" }, { local: true });
Custom models in collection works just like Backbone.js documentation
states. Just
override model
property in the collection with your custom Model class.
var Library = Backbone.SharedCollection.extend({
model: Book
});
If you want to have have multiple different Models in single SharedCollection, then you must do a small modification to your models. Set the type property of your custom models to some unique string identifier.
window.MyModel = Backbone.Model.extend({
type: "mymodel"
// Some custom method...
hasBar: function() {
!! return this.get("bar");
}
});
and pass those to the shared collection
var collection = new Background.SharedCollection([], {
collectionId: "mycollection",
modelClasses: [ MyModel ]
});
This way SharedCollection can know how to deserialize your custom models.
Remote updates will be emited as normal Backbone.js change
, add
, destroy
events. If you need to know whether the event came from ShareJS and not by local
code, you can check the options object of the event for remote
property.
model.bind("change", function(model, options) {
if (options.remote) {
// Came from remote browser
}
});
collection.bind("add", function(model, collection, options) {
if (options.remote) {
// Came from remote browser
}
});
When collection is properly connected to ShareJS a connect
event will be
emitted. You can also use success callback in fetch
method for this.
Synchronization errors will be emited as syncerror
events in SharedCollection instances.
collection.bind("syncerror", function(model, method, err) {
// `method` is a string, "add", "change" or "destroy", and `err` is the
// error object from ShareJS
alert("Failed to " + method + " " + model.id);
});
See User access control wiki page in ShareJS documention.
Set debugSharedCollection
in localStorage
to true to enable logging.
Install CoffeeScript and UglifyJS to build plain Javascript versions.
npm install -g coffee-script uglify-js
Use build
task in Cakefile to build it and watch
task can be use to
automatically to build it on changes.
- Initial release