Backbone.js provides a light-weight, extensible API which focuses primarily on general structure, and the utility of that structure, without requiring a rigid adherence to specific patterns or prescribing certain design philosophies. This focused approach affords developers a significant level of flexibility which can prove to be essential to the success of many modern client side web applications – especially when considering the challenges surrounding the ever changing landscape of the web.
Naturally, it follows that such flexibility imparts additional responsibility on the developer. In my experience with architectural frameworks in general, and Backbone in particular, many times this kind of trade off can be quite preferable.
Extending Backbone
As mentioned above, Backbone implements the essential building blocks necessary to provide general structure within an application. If a feature is needed which is not provided by default, by design, Backbone allows for easily extending the core APIs in order to implement additional features as needed. In fact, developers are encouraged to do so.
Perhaps a good example of this can be found in the need to persist collections in Backbone; that is, interestingly, while the Backbone Model API implements a default save method, the Backbone Collection does not provide a similar API for explicitly saving the models within a collection; that is, saving the collection itself. This feature may have been left out intentionally as part of an initial design decision, as there are some complexities to saving an entire collection as a general use-case; such as saving deltas, propagating saved state to models within the collection and so forth; or, perhaps it simply may have been an oversite. Regardless of the reason, in certain scenarios it can be useful to save an entire collection rather than saving each model individually – fortunately, given the flexibility of Backbone, writing an extension to implement this feature is quite simple.
The PersistableCollection
As a basic solution for saving a Backbone Collection, I wrote a general abstraction – PersistableCollection, which extends Backbone.Collection
, implementing a default save
method.
The PersistableCollection
API is quite simple in that it essentially just implements a proxy which wraps the collection in a Backbone Model, and ensures there is only one proxy created per collection. The url
and toJSON
methods, respectively, of the proxy Model reference the url
and toJSON
methods of the collection to which the proxy is bound. You can either extend PersistableCollection
or generate a proxy for an existing collection via the static createProxy
method. Examples of each follow.
Using a PersistableCollection
A PersistableCollection
can be instantiated and used directly, just like a Backbone.Collection:
1 2 3 4 5 6 7 8 9 | var users = new Backbone.PersistableCollection([ {name: 'Jane', id: 25}, {name: 'Joe', id: 26} ], { url: '/users'; ); users.save(); // saves the collection ... |
Extending PersistableCollection
You can extend PersistableCollection
and simply invoke save
to persist the models in the collection:
1 2 3 4 5 6 7 8 9 10 11 | var Users = Backbone.PersistableCollection.extend({ url: '/users', model: User }); var users = new Users([[ {name: 'Jane', id: 25}, {name: 'Joe', id: 26} ]); users.save(); // saves the collection .. |
Creating a proxy for an existing collection
An existing collection can be saved by creating a proxy for it:
1 2 3 4 5 6 7 8 9 | var users = new UsersCollection([ {name: 'Jane', id: 25}, {name: 'Joe', id: 26} ]); users.url = '/users'; var proxy = PersistableCollection.createProxy(users); proxy.save(); // saves the collection ... |
The PersistableCollection
can be used as a general extension for saving entire collections based on the representation of all models within the collection. If you are interested in extending it to account for more specific use-cases, you can simply override the default save implementation as needed.
You can find the gist for the source and spec here.
{Sorry, Comments are currently Closed! }