Backbone.js仍然在验证失败时设置模型属性

时间:2012-10-02 16:03:32

标签: javascript backbone.js

由于某些奇怪的原因,当我在模型验证中返回一个字符串时,我的模型仍在设置属性。这是我的代码验证代码:

Model = Backbone.Model.extend({
    validate: function( attributes ){
        var tax = attributes.tax;

        if(tax.amount < 0.0 || typeof tax.amount !== "number"){
            return "The tax amount cannot be negative and must be a number.";
        }
    },
   defaults: {
       "tax": {
            "amount": 100
       }
   },
   setTax: function(amount){
      var tax = this.get("tax");
      tax.amount = amount;
      this.set("tax", tax);
   }
})

然后我让模型侦听错误事件并通过控制台记录:

    model = new Model();

    View = Backbone.View.extend({
        initialize: function(){
            this.model.on('error', function(model, error){
                console.log("ERROR: " + error);
            })
        }
    });
    view = new View({model: model});
    view.model.setTax(-100);

正在打印控制台日志,但由于某种原因,模型仍在设置属性。有什么我需要返回到没有模型设置属性?根据Backbone.js码头,如果您从验证中返回任何内容,则假设不设置该属性。我正在使用Backbone.js版本0.9.2

1 个答案:

答案 0 :(得分:3)

你的问题就在这里:

var tax = this.get("tax");

get方法基本上是return this.attributes[attr],而tax属性是一个对象,结果是您的var tax和模型的this.attributes.tax是相同的事情。因此,当您说tax.amount = amount时,您实际上是直接编辑模型tax内的attributes

使用可变属性(即数字,字符串和布尔值以外的任何属性)时,您需要在更改之前进行复制:

setTax: function(amount) {
    var tax = _(this.get("tax")).clone();
    tax.amount = amount;
    this.set("tax", tax);
}

制作副本还可以防止Backbone认为您的set电话实际上没有做任何事情。如果您没有如上所述克隆tax,则不会在模型上触发更改事件,这可能不是您想要的。

一些例子(请打开你的控制台):