2013-01-25 20 views
21

私はBACKBONE.JSを学習し、この上の混乱しています: 私はチュートリアルの次のです:あなたが最初の例(1.js)で見ることができるよう http://arturadib.com/hello-backbonejs/いつBackbone.jsで_.bindAll()を使用する必要がありますか?

を:

(function($){ 
    var ListView = Backbone.View.extend({  
    el: $('body'), // attaches `this.el` to an existing element. 

    initialize: function(){ 
     _.bindAll(this, 'render'); // fixes loss of context for 'this' within methods 

     this.render(); // not all views are self-rendering. This one is. 
    }, 

    render: function(){ 
     $(this.el).append("<ul> <li>hello world</li> </ul>"); 
    } 
    }); 

    var listView = new ListView();  
})(jQuery); 

しかし、私が文章:_.bindAll(this, 'render');をコメントアウトすると、これはまだ動作します。私はgoogleで検索し、誰かが方法bindAll()が必要であると言いました。なぜなら私のコンテキストを切り替えると、this.renderの呼び出しは利用できなくなるからです。私は "文脈"に混乱しているように感じます。また、電話(this.render)が利用できなくなったときに私に説明する人もいますか?

答えて

26

は必要ありませんが、あなたがthisはおそらく何か他のコンテキストに変更することができるコールバック関数を持っている場合は、_bindAll()は便利です。例えば

initialize: function(){ 
    _.bindAll(this, 'render', 'clickFunc'); 
}, 
events: { 
    'click .someElement': 'clickFunc' 
}, 
clickFunc: function(e) { 
    /** If you remove the clickFunc from the list of events in bindAll, 
      'this' will refer to the element that invoked the event. 

     Adding the clickFunc event in the _.bindAll, ensures that 'this' stays 
      as the view. 
    */ 
    this /** <-- our focal point */ 
} 
+9

イベントの何かはバックボーン、FYIによって自動的にバインドされています。 –

+0

非常に素晴らしい説明、素晴らしい仕事 – M3ghana

2

この例では、あなたは_.bindAllが必要ですが、のはあなたのビューが再レンダリングを起こす方法があり、このような何かを言うことはできません。

.., 
myMethod: function() { 
    this.$('.someselector').change(this.render); 
}, 

あなたがrenderため_.bindAllを持っていない場合をあなたのコンテキストはオフになります。あなたのビューのイベントでプロパティ値として記載されている

10
  • 任意のメソッドが自動的にバックボーンによってあなたのため拘束されているハッシュ
  • 手動でモデルやコレクションからイベントハンドラとして使用し、あなたのビュー内の任意の方法は、手動でbindAll を介して結合されなければなりません
    • たり、同じ結果
  • を取得するために結合
  • または使用することができますEMCA 5のfunction.bindを登録するときは、コンテキストを提供することができます

スニペット:

events: { 
    'click .win': 'win', 
    'click .lose': 'lose' 
}, 
initialize: function() { 
    //win and lose are automatically bound for you 
    //because they are in the events property 

    //refresh must be manually bound 
    this.model.on('change', this.refresh); 

    //which you can do ECMA5 style if you like 
    this.model.on('change', this.refresh.bind(this)); 

    //OR you can provide a context backbone style 
    this.model.on('change:foo', this.fooChange, this); 

    //However, since you pretty much never want an unbound function 
    //in a view, you can just stick this in all your initialize methods 
    //and call it done 
    //Note this will bind all functions in your view class if you don't 
    //pass specific method names. I recommend this form. 
    _.bindAll(this); 
}, 
win: function() {...}, 
lose: function() {...}, 
refresh: function() {...}, 
fooChange: function() {...} 

... OOOOORRRRはただのCoffeeScriptと脂肪の矢印を使用してきれいに言語レベルでこれを解決。あなたが_.bindAll(this, 'render');を与えてくれた。例えば

+2

私はさらに_.bindAll(this)も好きですが、アンダースコアはそれをお勧めしません。1.5.0以降はサポートされなくなります。チェンジログには次のようなものがあります:メソッド名引数なしで_.bindAllを呼び出す機能を削除しました。バインドしたいメソッドの名前をホワイトリストに入れるほうがずっと賢明です。 http://underscorejs.org/#changelog私はそれがエラーだと思う。それは私を維持するのがはるかに困難です。 – ccsakuweb

+0

@ccsakuweb私は現在、私がバックボーンを大量に使用しているウェブインターフェースに取り組んでいます。このプロジェクトでは、私は現在、 '_.bindAll'を呼び出し、' _.bind'を呼び出しません。代わりに、私はモデルイベントを聞くために 'this.listenTo'を、DOMイベントのために' events'ハッシュを使い、代わりにそのようなコンテキストを提供します。 '_.bindAll'の1つの呼び出しは、' run'メソッドがそのコンテキストを失うようにする 'setTimeout(this.run、period)'を呼び出すバックグラウンドオートリフレッシャーの 'run'メソッドです。この点までは、 '_.bindAll'がなければ完全に扱えるようになりました。 –

2

_.bindAllunderscore.js offical docsから何をよく見てみましょう。

_.bindAll = function(obj) { 
    var i, length = arguments.length, key; 
    if (length <= 1) throw new Error('bindAll must be passed function names'); 
    for (i = 1; i < length; i++) { 
     key = arguments[i]; 
     obj[key] = _.bind(obj[key], obj); 
    } 
    return obj; 
    }; 

これは、すべての機能を自動的に正しいコンテキストにバインドすることです。 (その関数が宣言されたのではなく呼び出されるところ。

私は個人的にはそのevents、またはDOMのアクションリスナーをバインドするBACKBONE.JSの古いバージョンのための大会だったと思います。新しいバージョンのバックボーンViewが自動的eventsでリスナーをバインドし、バインド解除するので。検索で詳細を探すBinding "this"here

私はそれが役に立ちそうです。

関連する問題