最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I capture validation errors in a new Backbone.Model during instantiation? - Stack Overflow

programmeradmin4浏览0评论

It is easy to bind to the 'error' event of an existing model, but what is the best way to determine if a new model is valid?

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?

It is easy to bind to the 'error' event of an existing model, but what is the best way to determine if a new model is valid?

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?
Share Improve this question asked Oct 27, 2011 at 22:11 aw crudaw crud 8,89120 gold badges75 silver badges117 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 12

Validation logic can be triggered explicitly by calling the validate method of your model. This will not, however, cause an error event to be triggered. You can trigger an error event manually for a model by calling the trigger method.

One way to achieve your desired behavior is to manually trigger the event in your initialization method:

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 '';
  }
});

I haven't tested this, but I'm pretty sure that all events on all models in a collection will be passed to and triggered by the collection as well. So you should be able to listen to the error event on the collection:

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

Edit: Nope, this works for setting properties on existing models, but not on model creation. Ugh - it looks like there's no way to listen for this without overriding some part of the Backbone code. Models don't perform validation when they're initialized:

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

And while collection.add() does perform validation, it fails silently.

If you use collection.create() instead of collection.add(), you can check, since .create() will return false on failure. But this will try to create the model on the server, which might not be what you want.

So, I think the only way to do this is to override collection._prepareModel and trigger a custom event, like this:

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!'

Example here: http://jsfiddle/nrabinowitz/f44qk/1/

i encountered problem like it

my solution

...

var handler = function(model, error, context) {}

try {
  cars.add({}, { error: handler })
} catch (e) { }        

...
this.collection.fetch({
    validate: true
});
发布评论

评论列表(0)

  1. 暂无评论