如何在实例化期间捕获新的Backbone.Model中的验证错误?

时间:2011-10-27 22:11:18

标签: javascript backbone.js

很容易绑定到现有模型的“错误”事件,但确定新模型是否有效的最佳方法是什么?

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?

4 个答案:

答案 0 :(得分:12)

通过调用模型的validate方法可以显式触发验证逻辑。但是,这不会导致触发error事件。您可以通过调用trigger方法手动触发模型的错误事件。

实现所需行为的一种方法是在初始化方法中手动触发事件:

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

答案 1 :(得分:1)

我没有对此进行测试,但我非常确定集合中所有模型上的所有事件都将传递给集合并由集合触发。因此,您应该能够收听集合上的error事件:

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

编辑:不,这适用于设置现有模型的属性,但不适用于模型创建。呃 - 看起来没有办法在没有覆盖Backbone代码的某些部分的情况下听这个。模型在初始化时不执行验证:

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

虽然collection.add()执行验证,但它会无声地失败。

如果您使用collection.create()代替collection.add(),则可以检查,因为.create()将在失败时返回false。但是这会尝试在服务器上创建模型,这可能不是你想要的。

所以,我认为唯一的方法是覆盖collection._prepareModel并触发自定义事件,如下所示:

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

此处示例:http://jsfiddle.net/nrabinowitz/f44qk/1/

答案 2 :(得分:1)

我遇到了类似的问题

我的解决方案

...

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

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

...

答案 3 :(得分:0)

this.collection.fetch({
    validate: true
});