¿Cómo puedo capturar errores de validation en un nuevo Backbone.Model durante la creación de instancias?

Es fácil vincularse al evento 'error' de un model existente, pero ¿cuál es la mejor manera de determinar si un nuevo model es válido?

Car = Backbone.Model.extend({ validate: function(attributes) { if(attributes.weight == null || attributes.weight <=0) { return 'Weight must be a non-negative integer'; } return ''; } }); Cars = Backbone.Collection.extend({ model: Car }); var cars = new Cars(); cars.add({'weight': -5}); //Invalid model. How do I capture the error from the validate function? 

La lógica de validation se puede activar explícitamente llamando al método de validate de su model. Sin embargo, esto no provocará que se desencadene un evento de error . Puede desencadenar un evento de error manualmente para un model llamando al método trigger .

Una forma de lograr el comportamiento deseado es activar manualmente el evento en su método de initialization:

 Car = Backbone.Model.extend({ initialize: function () { Backbone.Model.prototype.initialize.apply(this, arguments); var error = this.validate(this.attributes); if (error) { this.trigger('error', this, error); } }, validate: function(attributes) { if(attributes.weight == null || attributes.weight <=0) { return 'Weight must be a non-negative integer'; } return ''; } }); 

No he probado esto, pero estoy bastante seguro de que todos los events en todos los models de una colección serán pasados ​​y activados por la colección también. Por lo tanto, debería poder escuchar el evento de error en la colección:

 var cars = new Cars(); cars.bind('error', function() { console.log('Model not valid!') }) cars.add({'weight': -5}); 

Editar : No, esto funciona para establecer properties en models existentes, pero no en la creación del model. Ugh, parece que no hay forma de escuchar esto sin anular una parte del código Backbone. Los models no realizan la validation cuando se inicializan:

 var car = new Car({weight: -5}); console.log(car.get('weight')); // no error, logs -5 

Y mientras collection.add() realiza la validation, falla silenciosamente.

Si usa collection.create() lugar de collection.add() , puede verificar, ya que .create() devolverá false en caso de error. Pero esto intentará crear el model en el server, que podría no ser lo que usted desea.

Por lo tanto, creo que la única forma de hacerlo es anular collection._prepareModel y activar un evento personalizado, como este:

 Cars = Backbone.Collection.extend({ model: Car, _prepareModel: function(model, options) { model = Backbone.Collection.prototype._prepareModel.call(this, model, options); if (!model) this.trigger('error:validation'); return model; } }); var cars = new Cars(); cars.bind('error:validation', function() { console.log('Model not valid!') }); cars.add({'weight': -5}); // logs: 'Model not valid!' 

Ejemplo aquí: http://jsfiddle.net/nrabinowitz/f44qk/1/

encontré un problema como este

mi solución

 ... var handler = function(model, error, context) {} try { cars.add({}, { error: handler }) } catch (e) { } ... 
 this.collection.fetch({ validate: true });