2011-10-25 5 views
2

이벤트 핸들러 인 기능을 모른다면 removeEventListener으로 전화하는 방법은 무엇입니까?Flex : removeEventListener 안전하게?

+0

물어볼 수 있습니다. 무엇을 위해 이러한 기능이 필요합니까? 유스 케이스 란 무엇입니까? – moropus

+0

나는 단지 1 개의 mothood를 가지고 단 한 번에 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'를 사용하여 두 번 호출했다고하더라도 매번 새로운 배열을 생성한다는 것을 알게 될 것입니다. 이러한 유형의 함수에 대해서는 다른 접근법을 권장하지만, 실제로이 방법을 사용하는 경우 사전에 "for for"루프가 필요하며 키의 값과 일치하는 속성을 가진 키를 찾으십시오 . – WORMSS

+0

@WORMSS 수정 해 주셔서 감사합니다. 나는 그 객체가 너무 원시적이지 않으며 참조로 전달된다는 것을 잊었다. 이 예제에서 가장 좋은 방법은 인수를 "someEventType : false"와 같은 문자열로 직렬화 한 다음 키로 사용하는 것입니다. –

+0

좋은 전화, 나는 결코 그 접근법을 생각하지 못했습니다. 나는 강하게 타이핑 한 것을 너무 좋아합니다. :디 – WORMSS

0

당신이 이해한다면, 다른 모든 이벤트 처리기를 제거하고 귀하의 것을 추가하고 싶습니다. AFAIK는 불가능합니다. 그리고 당신의 목표가 단 하나의 이벤트 리스너를 갖는 것이기 때문에 그것은 매우 이상한 행동입니다. 나는 깨끗하게하는 것보다 예방하는 것이 더 낫습니다.

preventDefault, stopPropagation 필요한 로그 램이있는 함수 또는 사용자 정의 클래스 (예 : 이벤트 대신 콜백이있는 항목)를 사용해보십시오.

+0

이 이벤트를 스팸으로 보내는 기능이 있습니다. 분당 천수와 같습니다. 이것은 선택 사항이 아닙니다. –

+0

그런 다음 익명의 함수를 사용하지 마십시오. 거의 항상 메모리 누수가 발생합니다. 현재 프로젝트에서 – moropus

+0

- 나는 anonimous 기능을 사용하는 것보다 다른 방법을 찾았습니다 ... 실제로 anonimouse가 아니지만 서로를 교환하고 있습니다 ... : | –

1

이 시도 :

obj.addEventListener(MouseEvent.CLICK, function(event :Event):void 
{ 
    obj.removeEventListener(MouseEvent.CLICK, arguments.callee); 
}); 
관련 문제