2012-03-15 43 views

回答

13

試試這個:

e.currentTarget.removeEventListener(e.type, arguments.callee) 
5
  1. 你不應該做你的代碼做什麼上面。

  2. 如果事件的currentTarget沒有removeEventListener()方法(可能,但不太可能),則mgraph的代碼有很小的機會無法工作。從編譯器的角度來看,儘管您將嘗試動態地解決容易出錯並且應該小心處理的通用對象上的方法。這是很危險的,因爲它表明程序員「不知道」她期望通過假設處理和工作的對象是什麼類型。假設對於找到解決方案非常有用,但對於實施解決方案同樣不利。

如果你覺得你做到了,那麼,只是FYI這實際上會在符號表中唯一的(冗餘)名稱(在編譯的SWF文件),這將導致的較差的壓縮方式優化東西SWF。

如果你是在做實驗,這很好,但是你應該在實際項目中避免這樣的代碼。

還有一件事要注意:與true常數比較是100%無用的。如果這種比較有任何意義(即findObject可隨時評估爲false),那麼if (findObject) { ... }是等效的,但代碼的版本較短。 最後一件事,希望匿名函數缺少返回類型聲明。在你的例子中它不會有太大的改變,除非你會得到編譯器警告。一般而言,省略型申報是一種不良風格。

編輯

public function addEventListener(type:String, listener:Function ...):void 
{ 
    this._listeners[type].push(listener); 
} 

public function dispatchEvent(event:Event):void 
{ 
    for each (var listener:Function in this._listeners[event.type]) 
     listener(event); 
} 

public function removeEventListener(type:String, listener:Function, ...):void 
{ 
    delete this._listeners[type][listener]; 
} 

假設你真正想實現實現IEventDispatcher(而不是使用此事件的另一個 - 你可以有你的理由這樣做,這樣的一個原因是,此事件本土產生大量瘋狂的短),但是您無法在代碼中複製event.target或event.currentTurget,因爲您無法訪問擁有該方法的對象,因此,您將離開該對象出。

又如:

public class SomeEvent extends Event 
{ 

    private var _target:NotEventDispatcher; 

    public function SomeEvent(type:String, someTarget:NotEventDispatcher) 
    { 
     super(type); 
     this._target = someTarget; 
    } 

    public override function get target():Object 
    { 
     return this._target; 
    } 
} 

這是什麼,其實我在現實世界中看到的,這是在任何Mate或其他類似的框架用來排序的「匿名」的所有事件派發連接到一個單一的靜態實例一些「母親事件調度員」。

我不一定要證明這種方法,但從技術上來說,沒有任何東西可以阻止你做任何一種方法。上面我說的話在我的崗位是,在某些情況下,語言承諾你的東西,比如,如果你這樣做:

var dispatcher:IEventDispatcher; 
try 
{ 
    dispatcher = IEventDispatcher(event.currentTarget); 
    // now you can be sure this object has removeEventListener 
    dispatcher.removeEventListener(event.type, arguments.callee); 
} 
catch (error:Error) 
{ 
    // but what are you going to do here? 
} 

但最常見的情況是您訂閱冒泡事件,在這種情況下,你不知道你是否想取消訂閱活動。target或event.currentTtarget - 因爲你不知道你在聽哪一個。

+0

我很好奇'currentTarget'不會是'EventDispatcher'的情況。我不明白怎麼會有理由發生...... – 2012-07-26 14:01:53

+0

我不太喜歡,如果你是嘲弄和'IEventDispatcher',那麼'e.currentTarget'就是'this',它保證有一個'removeEventListener'因爲它是一個'IEventDispatcher'。除了一個簡單的方法來模擬'EventDispatcher'只是一個'EventDispatcher'的新功能。除非你試圖*嘗試*來破壞事件堆棧 - 或者故意嘗試不滿足事件堆棧的依賴關係--e.currentTarget將始終指向具有removeEventListener的東西的實例'定義...對我來說,這是一個不完整的模擬,而不是解決方案的問題。 – 2012-07-27 02:51:11

+0

我明白你現在要去的地方。 – 2012-07-27 11:34:08

1

我同意wvxvw。

另一種方式來處理你的問題是有一個變量來控制你的ENTER_FRAME事件的「狀態」:

private var _state:String; 

private function init(e:Event):void { 
    addEventListener(Event.ENTER_FRAME, loop, false, 0, true); 
} 

private function loop(e:Event):void { 
    switch(_state) { 
     case "play": 
      // do play stuff 
      // when you want to pause 
      // goToPause(); 
     break; 
    } 
} 

// you can call the method below from a button or whatever you want 
private function goToPause():void { 
    _state = "pause"; 
    // do some stuff here 
    // when you are done, switch "_state" back to "play" 
} 

在這個例子中,你要繼續收聽ENTER_FRAME,但它只是做的事情時, _state變量被設置爲「play」。您還可以刪除事件偵聽器在goToPause方法:

private function goToPause():void { 
    _state = "pause"; 
    removeEventListener(Event.ENTER_FRAME, loop); 
} 

然而,有關使用「_STATE」切換事情好處是,你最終不會有addEventListeners和removeEventListeners亂七八糟的(這是什麼可能發生取決於你的循環得到多麼複雜),你必須跟蹤。

0

如果您想在一段時間後刪除偵聽器,則不應使用匿名函數調用。

public function main():void 
{ 
    //... 
    //some method, where you add event listener 
    //... 

    //adding enterFrame event listener 
    this.addEventListener(Event.ENTER_FRAME,enterFrameHandler); 

    //... 

} 

private function enterFrameHandler(e:Event) 
{ 

    if(findObject) // " == true" is not really necessary here. 
    { 
     // removing enterFrame listener: 
     this.removeEventlistener(Event.ENTER_FRAME,enterFrameHandler); 
    } 
} 
0

只是與這裏提到的其他技術完備性,你所創建的函數是綁定關閉,所以你也可以利用這個概念同時引用您的功能和調度。

var callback:Function; 
var dispacher:IEventDispatcher = this; 
addEventListener(Event.ENTER_FRAME, callback = function(e:Event){ 

     if(findObject == true){ 
      dispacher.removeEventListener(Event.ENTER_FRAME, callback); 
     } 

}); 

正常結束變量規則適用。