2009-11-26 7 views
7

私はサードパーティ製のフラッシュオブジェクトを用意しています。これらのオブジェクトは、提供しているJavaScript APIを通じて操作できます。私はこのオブジェクトのイベントを聞いて試してみると、オブジェクトの中でイベントを発生させ、イベントをさらに泡立たせます。私はEXT Jsを使用していますが、ここでは重要ではないと思います。addEventListenerとthisのスコープ

サンプルコード

this.chart.addEventListener('create', function() { 
    this.fireEvent('created'); 
}, false) 

私の問題は、匿名関数内の「これは」私は上のイベントを発生するイベントではなく、私のオブジェクトを解雇したオブジェクトを参照すること。あります

さらに別の範囲の問題です。助けを前にありがとう。

答えて

0

: - 他の回答はあなたが必要なものを達成しながら

(function(self) { 
    self.chart.addEventListener('create', function() {self.fireEvent('created');}, false); 
})(this); 
+2

私は 'var self = this;'が好きです。関数を作成して、それをパラメータとして渡している間に 'this'を渡すのはちょっと戸惑っているようです.- –

+0

@Andy:そうですね、小さな実行コンテキストにコードが存在するとしばしばそうします。しかし、上記は、より広範なシナリオで機能する標準的なアプローチです。'self'識別子の範囲はクロージャーにのみ制限されます。イベントが発生する前に後続コードがその値を変更する危険はありません。これは 'var self = this;'アプローチには当てはまりません。 – AnthonyWJones

12

'this'オブジェクトを参照する前に外部変数を作成することはどうでしょうか。たとえば :これは、この問題に対する典型的なアプローチである

var _this = this; 
this.chart.addEventListener('create', function() { _this.fireEvent('created'); }, false) 
+4

はい、これは通常のイディオムです。クロージャ変数はしばしば 'that'または' self'と呼ばれます(私は後者が 'self'が確立しているとは思いませんが、JavaScriptでは意味がありません)。 – bobince

+0

OKです。興味のないものは、これに変数を設定する以外の方法があります。たとえば、クロージャを使用して? – Jonnio

+1

@bobince:私は 'self'を好む。 'self'は' window'によってそれ自身への参照として公開されます。私は他のスコープで識別子を再利用することができてとても嬉しいです。正しい意味を持ち歩くように思われ、「自己」がウインドウになったときにそれが衝突することはありません。 – AnthonyWJones

5

、彼らが最も効率的な(スケーラブルな)方法では動作しません。そのビューのロジック(fireEvent())からビューオブジェクト(this.chart)を最終的に分離しないためです。 MVCアプリケーションでは、これらのビュー "決定"はコントローラにあります。コントローラはビュービューを「制御」し、ビューがアクセスできるすべてのAPIを含める必要があります。

あなたの例では、thisがコントローラであり、これはうまくいきます(適切な場所にリスナーを追加していることを意味します)。あなたが本当にやらなければならないことは、「取り扱い」やるべき事の範囲にハンドラをバインドしている - あなたのケースでは:this

// `this` is the controller of `chart` 
this.chart.addEventListener('create', function() { 
    this.fireEvent('created'); 
}.bind(this)); 

何、このページの他の回答を行っていることは、それを作っていますあなたのビューはそれ自身のコントローラーになりますが、「コントローラ」への一時的な参照をvar self = thisを使用して割り当てて、「作成」イベントを処理するときだけです。繰り返しますが、これはうまくいきますが、イベントドリブンアプリケーションではうまく機能せず、処理するイベントがたくさんある場合には意味がありません。

.bind()は、ECMAScript 5実装です。古いブラウザでも作業する必要がある場合は、ここで説明します(functions.call())。https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind

+0

いくつかのMVC実装(ここで説明した例のようにhttp://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)では、ハンドラ自体(例えば、あなたの '.fireEvent ) ')がビューに定義されていますが、コントローラは必要に応じてそれを呼び出します。これはあなたが '.bind()'や自己参照を全く使わないようにするかもしれませんが、あなたのハンドラは非常に非形式的になります。あなたのアプリケーションは非常に大きくなるでしょう。 – Benny

関連する問題