0

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

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

4

1 回答 1

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上述内容,您将不会触发模型上的更改事件,这可能不是您想要的。

几个例子(请打开你的控制台):

于 2012-10-02T17:07:03.533 回答