2011-10-25 18 views
2

イベントハンドラである機能がわからないときにremoveEventListenerに電話する方法はありますか?Flex:removeEventListenerは安全ですか?

+0

私はあなたに何を求めていますか?そのような機能は何のために必要ですか?ユースケースは何ですか? – moropus

+0

私は一度に1つの偶数ハンドラを使用する必要があります。 –

答えて

1

EventDispatcherの独自の実装を作成する必要があります。悲しいですが、ネイティブのIEventListenerプロトタイプはたくさんの便利なメソッドを提供していません。あなたがあなたのケースであなたは一度だけ使用すると、使用できるよりもイベントを発生する必要があることを述べたようにそれ以外の場合は

package { 
import flash.events.EventDispatcher; 
import flash.utils.Dictionary; 

/** 
* Advanced Event Dispatcher with a ability to remove all listener by event type 
* @author Rytis Alekna 
*/ 
public class AdvancedEventDispatcher extends EventDispatcher { 

    /** This var holds all references to listeners */ 
    protected var eventListenersByType : Dictionary = new Dictionary(true); 

    /** 
    * Call this method to remove all listeners of specified type 
    */ 
    public function removeEventListenersByEventType (type : String, useCapture : Boolean = false) : void { 

     var key : String = type + ":" + useCapture; 

     if (this.eventListenersByType[ key ] && this.eventListenersByType[ key ].lenght > 0) { 

      // copy array of event listeners 
      var listenersToRemove : Array = this.eventListenersByType[ key ].concat(); 

      // and clear original 
      this.eventListenersByType[ key ] = []; 

      // loop over all listeners 
      for (var i : int = 0; i < listenersToRemove.length; i++) { 
       this.removeEventListener(type, (removeEventListenersByEventType[i] as Function), useCapture); 
      } 

     } 

    } 

    /** 
    * Override this method to implement listeners registration by type. 
    */ 
    override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false) : void { 

     // register with native method 
     super.addEventListener(type, listener, useCapture, priority, useWeakReference); 

     // create a key for storage 
     var key : String = type + ":" + useCapture; 

     // check if it doesn't already exist 
     if (!this.eventListenersByType[ key ]) { 
      this.eventListenersByType[ key ] = []; 
     } 

     // push listener to our storage 
     this.eventListenersByType[ key ].push(listener); 

    } 

} 

}

その実装は次のようになりますかのサンプルコードがありますAS3の信号のような便利なフレームワーク(http://johnlindquist.com/2010/01/21/as3-signals-tutorial/)

+1

私はこの '上記の行から!(!this.eventListenersByType [key]) 'を実行すると、あなたは名目上のオブジェクトの「新しいインスタンス」を作成しています。したがって、すでに辞書に入っている可能性はありません。同じ 'type'と' useCapture'で2回呼び出したとしても、そのたびに新しい配列が作成されます。このタイプの関数では、私は別の方法をお勧めしますが、実際にこのようにしている場合は、辞書の "for"ループが必要で、一致するプロパティを持つキーを見つけてそのキーの値に押し込む必要があります。 – WORMSS

+0

@WORMSSありがとうございます。私はオブジェクトがそれほど原始的ではなく、参照によって渡されていることを忘れていました。この例では、引数を "someEventType:false"のような文字列にシリアル化してキーとして使用するのが最善の方法です。 –

+0

良いコール、私はそのアプローチを考えたことはありません。私は強く入力したものがあまりにも好きです。 :D – WORMSS

0

私があなたのことをよく理解していれば、他のすべてのイベントハンドラを削除して追加したいと思うでしょう。それは不可能です、AFAIK。あなたの目標はイベントリスナーを1つしか持たないからです。私はきれいにするよりも予防​​する方がいいでしょう。

preventDefault,stopPropagation必要なログ(イベントの代わりにコールバックを持つものなど)を使用して、関数またはカスタムクラスを使用することを検討してください。

+0

このイベントをスパム送信する機能があります。毎分千分の一に似ています。これはオプションではありません。 –

+0

次に、匿名関数を使用しないでください。ほとんどの場合、メモリリークが発生します。現在のプロジェクトで – moropus

+0

- 異種機能を使用するよりも別の方法を見つけることはできません...実際には全く同じではなく、お互いに交換しています...:| | –

1

はこれを試してみてください:

obj.addEventListener(MouseEvent.CLICK, function(event :Event):void 
{ 
    obj.removeEventListener(MouseEvent.CLICK, arguments.callee); 
}); 
関連する問題