Often times I find the native Backbone Collection implementation to be lacking when compared to it’s Backbone.Model counterpart. In particular, Collections generally lack in terms of direct integration with a backend persistence layer, as well as the ability to validate models within the context of the collection as a whole.
Fortunately, such short comings can easily be circumvented due to the extensibility of Backbone’s design as a generalized framework. In fact, throughout my experience utilizing Backbone, I can assert that there has yet to be a problem I have come across which I was unable to easily solve by leveraging one of the many Backbone extensions, or, more often than not, by simply overriding Backbone’s default implementation of a given API.
Validating Collections
Perhaps a common use-case for validating a collection of Models can be found when implementing editors which allow for adding multiple entries of a given form section (implemented as separate Views), whereby each section has a one-to-one correlation with an individual model. Rather than invoke validation on models from each individual view, and manage which model’s are in an invalid state from the context of a composite view, it can be quite useful to simply validate the collection from the composite view which, in turn, results in all models being validated and their associated views updating accordingly.
Assuming live validation is not being utilized, validation is likely to occur when the user submits the form. As such, it becomes necessary to validate each model after their views have updated them as a result of the form being submitted. This can be achieved quite easily by implementing an isValid
method on the collection which simply invokes isValid
on each model within the collection (or optionally, against specific models within the collection). A basic isValid
implementation for a Collection is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | /** * Provides a convenience method which determines if all models * within this collection are currently in a valid state. * * @example * // true if all models in the collection are valid, * // otherwise, false * collection.isValid(); * * // spec examples ... * describe('isValid', function(){ * var Model = SomeModel.extend({ * defaults: {'id': NaN}, * validate: function(attrs){ * return isNaN(attrs.id) ? 'Invalid' : undefined; * } * }); * describe('invalid models', function(){ * it('should return false if any models are invalid', function(){ * expect(new SomeCollection([ * new Model(), * new Model({'id': 1}) * ]).isValid()).toBeFalsy(); * }); * }); * describe('valid models', function(){ * it('should return true if all models are valid', function(){ * expect(new SomeCollection([ * new Model({'id': 0}), * new Model({'id': 1}) * ]).isValid()).toBeTruthy(); * }); * }); * }); * ... * * @method isValid * @return {Boolean} returns true if all models are valid, * otherwise, false. */ isValid: function() { return _.every(this.models, function(model){ return model.isValid(); }); } |
As can be seen in the above example, the Collection’s isValid
method simply invokes isValid
on it’s models. This causes each model to be re-validated which, in turn, results in any invalid models triggering their corresponding invalidation events, allowing for views to automatically display validation indicators, messages, and the like; particularly when leveraging the Backbone.Validation Plugin.
This example serves well to demonstrate that, while Backbone may not provide everything one could ever ask for “out of the box”, it does provide a design which affords developers the ability to quickly, easily, and effectively extend the native framework as needed.
{Sorry, Comments are currently Closed! }