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直接編集しています。taxattributes

変更可能な属性 (つまり、数値、文字列、およびブール値以外のもの) を操作する場合、それらを変更する前にコピーを作成する必要があります。

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 に答える