2012-02-24 8 views
8

私がやりたいことはかなりシンプルですが、どうやってそれを行うのか分かりません。イベントハンドラにデータを渡す目的で、モデルの属性の1つが変更されたとき(値が増減したかどうかにかかわらず)、私自身のイベントを開始したいと思います。バックボーンモデルを上書きする変更イベント

は基本的に私は私のハンドラがビュー

handler: function(increased) { 
    if(increased) { 
     alert("the value increased") 
    } 
    else { 
     alert("the value decreased") 
    } 
} 

// ... 

this.model.on("change:attr", this.handler, this); 
+1

何がうまくいかない? – tkone

+0

hmmm多分私の質問がはっきりしないかもしれませんが、データを 'change:attr'ハンドラに渡す方法を知りたいのですが、私は' set() 'を呼び出すたびにイベントがバックボーンによって"自動的に "モデル。 – Matthew

+0

どのデータを渡しますか?すでにモデルにアクセスすると、変更された属性がわかります。 – tkone

答えて

12

ここに行きます:あなたは基本的にchange:myvarを聞きます。変更が発生すると、モデルのprevious()を使用して古い値を取得します。それが増減したかどうかによって、適切な事象が発生します。 initialize()に示すように、これらのイベントを聴くことができます。

(function($){ 

    window.MyModel = Backbone.Model.extend({ 

     initialize: function() { 
      this.on('change:myvar', this.onMyVarChange); 
      this.on('increased:myvar', function() {     
       console.log('Increased');     
      }); 
      this.on('decreased:myvar', function() {     
       console.log('Decreased');     
      }); 
     }, 

     onMyVarChange: function() { 
      if (this.get('myvar') > this.previous('myvar')) { 
       this.trigger('increased:myvar'); 
      } else { 
       this.trigger('decreased:myvar'); 
      } 
     }    
    }); 

    window.mymodel = new MyModel({myvar: 1}); 
    mymodel.set({myvar: 2}); 
    mymodel.set({myvar: 3}); 
    mymodel.set({myvar: 1}); 

})(jQuery);​ 

上記を実行すると、コンソールに「増加」、「増加」、「減少」が表示されます。

+0

これはとても良い解決策のようです。それを試して、そして戻って戻ってくるだろう... – Matthew

+0

作品は素晴らしい、受け入れ – Matthew

+0

かなりうまく、頭のおかげで動作します。私の場合は、添付されたモデルを持つビューでイベントを検出する必要がありました。したがって、モデルの値がDOM入力から変化したときだけでなく、モデルがビューにアタッチされても、イベント 'change:attribute_name 'がトリガされます。そこで、 'this.model.get( 'attribute_name')'がヌルであるかどうかをチェックして、 'initialize'メソッドの中でトリガされたイベントを検出しないようにしなければなりませんでした。 – codarrior

0

でこれをやりたい変更イベントを聞いた後、独自のカスタムイベントを発生か?

handler: function(increased) { 
    this.model.trigger('my-custom-event', stuff, you, want); 
}, 
myHandler: function(stuff, you, want){ 
    // Do it... 
} 
// ... 
this.model.on("change:attr", this.handler, this); 
this.model.on('my-custom-event, this.myHandler, this); 
2

はちょうどあなたがそれから比較することができpreviousAttributes()

を見て:

If(this.get(attr) > this.previousAttributes()[attr]){ 
    console.log('bigger'); 
} else { 
    console.log('smaller'); 
} 

あなたchangeイベントハンドラでは、すべてのセットだと使用している場合。カスタムトリガーや大量のコードは必要ありません。

EDIT

これは私のBackbone.Validatorsプロジェクトからのものであり、どのように私は、検証段階の間に変更されたすべての属性のリストを得る:それは_.hasを使用しているため

var get_changed_attributes = function(previous, current){ 
    var changedAttributes = []; 
    _(current).each(function(val, key){ 
     if(!_(previous).has(key)){ 
      changedAttributes.push(key); 
     } else if (!_.isEqual(val, previous[key])){ 
      changedAttributes.push(key); 
     } 
    }); 
    return changedAttributes; 
}; 

これはアンダー1.3.1が必要です。あなたがアップグレードすることができない場合は、簡単に置き換えることです。あなたのケースでは、あなたは渡すだろうthis.previousAttributes()this.attributes

+0

これは@ggozadが思い付いたものと似ています。私は 'this.on( 'changed:attr'')を聞いて、ハンドラでカスタムイベントを発生させるというアイデアが好きだったので、私は彼を受け入れた。 – Matthew

+0

@matthew Yup。これが最良の方法です。これは、必要に応じて再利用を容易にする属性を比較することで一般的に行うことができるという考え方です。フィードバックをお寄せいただきありがとうございます! – tkone

関連する問題