4

私はbindAllを使用する際に問題があります。私が得るエラーはfunc is undefinedです。私が間違ってやっていることに関する考えは?バックボーンとbindAll: "funcは未定義です"

私は

  • bindAll(上記のエラーで失敗)、そしてあなたがCoffeeScriptのを使用している
  • 個々bind S(動作しない)
window.test = Backbone.View.extend({ 

    collection: null 

    initialize: -> 
    console.log('initialize()') 
    console.log(this) 
    # _.bindAll(this, ["render", "foo"]) 
    _.bind(this.render, this) # these don't throw errors, but binding won't work 
    _.bind(this.foo, this) 
    @collection = new Backbone.Collection() 
    @collection.bind "add",  @render 
    @collection.bind "add",  @foo 
    @render() 

    foo: -> 
    # won't be bound to the view when called from the collection 
    console.log("foo()") 
    console.log(this) 
    console.log(this.collection) # undefined (since this is the collection, not the view) 

    render: -> 
    console.log("render()") 
    console.log(this) 
    return this 

}) 
testInstance = new window.test(); 
# using _.bind instead of bindAll we get past this point, however this won't be the view 
testInstance.collection.add({}) 

答えて

11

の両方を試してみました、アンダースコアのバインドは必要ありません。しかし、_.bindAllに関して、あなたにメソッド名を指定する必要はありませんhttp://jashkenas.github.com/coffee-script/

:CoffeeScriptのは、それだけで「脂肪矢」ここ「脂肪矢印」の

foo: => 
    #Your foo implementation goes here 
render: => 
    # your render implementation goes here 

検索を使用中に組み込まれています配列。 _.bindAll(this)または_.bindAll(this, 'render', 'foo')(メソッド名は明示的なリストではなく、var argsです)のいずれかを実行できます。それが役立つかどうかを見てください。

+0

太い矢印をバックボーンモデルの「メソッド」で機能させることはできませんでした。 あなたは正しく、私のbindAll構文が間違っていました。ありがとう! – sandstrom

+0

太った矢も私の問題を解決しました、ありがとう! – pws5068

8

ピーター・ライアンは、両方のカウントで正しいです。関数の配列を渡すのではなく、bindAllの引数として各関数を渡したいとします。また、coffeescriptを使用しているときに太い矢印は、定義されたコンテキストに関数をバインドする素晴らしい方法です。

なぜ答えが _.bindがあなたのために働いていなかったのですか(それは私がそれを理解するのには良い時があったからです)。答えは_.bindが渡した関数を変更しないということです。引数を指定して新しい関数を作成します。より適切にはcreateBoundFunctionというラベルが付けられます。だから、_.bindはあなたの例で動作するようになっては、単に次のようになります。

さらに
this.render = _.bind(this.render, this) 
this.foo = _.bind(this.foo, this) 

、私は機能が、私はあなたが結合機能に余談を気にしないことを望むようにバインドされているかについて多くのことを学んだソースをステップ実行するときコーヒースクリプトが何をしているかで始まります。

var __bind = function(fn, me){ return function(){return fn.apply(me, arguments); }; } 

のCoffeeScript脂肪矢印(=>)を使用して各ファイルに上記の関数を挿入します。これは古い方法です。関数を呼び出して渡すコンテキストと引数を適用する新しい関数を作成して返します。次に、CoffeeScriptはコンストラクタを生成し、太矢印で定義された各関数に対して__bindを呼び出します。ピーター・リヨンの解決のために生成されたコードは次のようになります。私の現在のプロジェクトで

this.render = __bind(this.render, this) 
this.foo = __bind(this.foo, this) 

を私は脂肪の矢印を使用して9つの見解を持っているので、私は、9回定義一見DRY違反しているが、誰が気に、そのために生成__bindています私。

ECMAScript5は、関数プロトタイプに対して新しいメソッドを宣言します。

Function.prototype.bind(thisArg [, arg1[, arg2[, ...]]]) 

このメソッドは、このように見えるようにコードを削減する:なし外部のライブラリや生成されたメソッドに必要と

this.render = this.render.bind(this) 
this.foo = this.foo.bind(this) 

。キャッチは、これは最新の+最高のブラウザー(FF4、IE9、CH10>)でのみサポートされているため、これを数年間使用することはできません。

下線は、これら二つの概念を組み合わせ:

_.bind = function(func, obj) { 
    if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); 
    var args = slice.call(arguments, 2); 
    return function() { 
    return func.apply(obj, args.concat(slice.call(arguments))); 
    }; 
}; 

nativeBindはFunction.prototype.bindに等しいです。したがって、アンダースコアは新しいECMA5バインドメソッドの可用性をチェックし、存在しない場合は、選択したコンテキストで関数を呼び出す無名関数を作成します。

Function.prototype.bindが与える利点について知っていたり、CS太った矢印を避けて_.bindを使用すると、特にあなたのアンダースコアが既に含まれているバックボーンプロジェクトライブラリがありますが、私はそれが利点を与えることを知らないので、おそらくどちらか一方の方法では関係ありません。

+0

すばらしい説明 – emilebaizel

1

バックボーンで、追加のパラメータを追加して、thisをコールバックにバインドできるようになりました。 http://documentcloud.github.com/backbone/#FAQ-thisを参照してください。この方法では、ビューのメソッドはコレクションではなくビューにバインドされます。