2011-09-16 3 views
0

私はこの問題を解決するために何時間も探してきました。私はprototype.js 1.6.0.1を使用してテーブルを作成していますが、.each関数のコンテキストでこのオブジェクトに問題があります。ここにスニペットがあります。prototype.jsの無名関数内の "this"に関する質問。それぞれのメソッド

var Table = Class.create({ 
    initialize : function(id) { 
    this.elmnt = $(id); 
    this.rows = []; 
    }, 
    initRows : function() { 
    $A(this._elmnt.tBodies).each(function(body) { 
     $A(body.rows).each(function(row) { 
     //right here is where i would like to call 
     // this.rows.push(row); 
     console.log(this); // prints DOMWindow 
     }); 
    }); 
    } 
}); 

2番目の.each関数の内部にあるように、これはDOMWindowに解決されます。私はthis.rows.push(row)に電話することができるようにしたいと思いますが、 "これ"が期待どおりに解決していないため、できません。

ご協力いただければ幸いです。私は標準(私は0;私は<長さ、私は+ +)ループを行うことができる知っているが、私はこれを少しきれいにしようとしていた。あなたが提供できるガイダンスをありがとう。

+0

'Table'オブジェクトに行のコレクションを維持する理由はありますか? 'HTMLTableElement'は既に独自のコレクションを保持しています。 'this.elmnt.rows'または' this.elmnt.tBodies [0] .rows'です。 – user113716

+0

https://developer.mozilla.org/en/DOM/table.rows – user113716

+0

これは、私が 'each()'をオーバーライドする実装が気に入らない理由です。そしてなぜ私はコーヒースクリプトが好きなのですか?それは非スコープの導入と非コンテキストのレイピングアレイ反復です。 –

答えて

4

あなたに実行している問題はthisがによって操作することができるということであるeach機能

initRows : function() { 
    var self = this; 
    $A(this._elmnt.tBodies).each(function(body) { 
     $A(body.rows).each(function(row) { 
     //right here is where i would like to call 
     self.rows.push(row); 
     console.log(self); // prints DOMWindow 
     }); 
    }); 
    } 

内でこの問題を回避する最も簡単な方法は、initRowsの開始時にthisを保存し、参照することです関数の呼び出し元。コールバックでは、コールバックに関連する要素にthisを設定するのが一般的です。 eachの場合は、値の現在の反復の要素に設定されます。

selfトリックは、にバインドされたとおりにthisを保存してから、その保存された値を繰り返し使用するために機能します。

+0

ありがとう、これは助けになりました。それは私がこれに再び遭遇するかどうかを知る良いことです。 var self = thisについては興奮していませんが、これは古き良きループ型のインデックスよりはるかに優れたソリューションです。 – kwbock

+2

@grizzgreen:変数が気に入らなければ、[Prototypejsの '.bind()'メソッド](http://api.prototypejs.org/language/Function/prototype/bind/)を代わりに使用してください。 – user113716

+0

+1をスコープや文脈と混同することなく*この*の説明が良い。 :-) – RobG

0
initRows : function() { 
    $A(this._elmnt.tBodies).each(function(body) { 
     $A(body.rows).each((function(e, row) { 
      e.rows.push(row); 
      console.log(e); 
     }).bindAsEventListener(this, row)); 
    }); 
} 
+0

私はこれに同意しません。それぞれのコールバックはイベントではなく、 'bindAsEventListener()'にする必要はありません。また、 '(each) 'の2番目のパラメータ(http://api.prototypejs.org)/language/Enumerable/prototype/each /)はコンテキストです。バインドされている場所で 'row'が存在しないのでカリー化できません。' row'はコールバック内にのみ存在します。コールバックのコンテキストをバインドしようとしても、その中に 'this'を使用する例はありません。コールバックのパラメータは間違っています。 '(row、index)'でなければなりません。 'index'はオプションです。 – clockworkgeek

関連する問題