2010-03-19 18 views
5

Ich bin auf der Suche nach einer Möglichkeit, einen EventListener hinzuzufügen, der sich automatisch nach dem ersten Mal löscht, aber ich kann mir nicht vorstellen, wie ich das machen möchte .AS3 - Ereignis-Listener, der nur einmal auslöst

fand ich diese Funktion (here):

public class EventUtil 
{ 
    public static function addOnceEventListener(dispatcher:IEventDispatcher,eventType:String,listener:Function):void 
    { 
     var f:Function = function(e:Event):void 
     { 
       dispatcher.removeEventListener(eventType,f); 
       listener(e); 
      } 
      dispatcher.addEventListener(eventType,f); 
    } 
} 


Aber anstatt schreiben:

EventUtil.addOnceEventListener(dispatcher, eventType, listener); 

Ich möchte es die übliche Art und Weise nutzen:

dispatcher.addOnceEventListener(eventType, listener); 


Hat jemand eine Idee davon, wie das sein könnte ne?
Jede Hilfe würde sehr geschätzt werden.


(Ich weiß, dass Robert Penners Signals dies tun können, aber ich kann sie nicht verwenden, da es eine Menge Code würde bedeuten, Umschreiben, dass ich nicht für ein aktuelles Projekt leisten können)

+0

Versuchen Sie, die [Signale Library] (https://github.com/robertpenner/as3-signals/wiki) verwendet wird. –

Antwort

11

Ich finde die sauberste Weg, ohne Statik oder vermasselt Ihren Code mit Rauschen verwendet, ist eine globale Funktion zu definieren (in einer Datei namens removeListenerWhenFired.as) wie folgt:

package your.package 
{ 
    import flash.events.Event; 
    import flash.events.IEventDispatcher; 

    public function removeListenerWhenFired(callback:Function, useCapture:Boolean = false):Function 
    { 
     return function (event:Event):void 
     { 
      var eventDispatcher:IEventDispatcher = IEventDispatcher(event.target) 
      eventDispatcher.removeEventListener(event.type, arguments.callee, useCapture) 
      callback(event) 
     } 
    } 
} 

Dann können Sie hören für Veranstaltungen wie so:

import your.package.removeListenerWhenFired 

// ... class definition 

    sprite.addEventListener(MouseEvent.CLICKED, 
     removeListenerWhenFired(
      function (event:MouseEvent):void { 
       ... do something 
      } 
     ) 
    ) 
+0

Das ist ein schöner Trick, an den ich nicht gedacht habe, danke! –

+0

kein Problem;) Verschlüsse sind in der Tat sehr praktisch. Ich baue eine ganze Tasche voll mit Schließ- und globalen Funktionstricks, um zu sehen, wohin alles geht. –

+0

Wie würden Sie einen solchen Listener manuell entfernen, da der hinzuzufügende Listener eine anonyme Funktion ist? Wenn Sie es nicht manuell entfernen können, dann werden Sie früher oder später auf einen Fehler prüfen. – chichilatte

2

I Ich habe es nicht ausprobiert, aber Sie könnten einfach die statische Methode EventUtil in eine Standardmethode umwandeln und die Klasse in Ihrem Objekt erweitern.

public class OnceEventDispatcher 
{ 
    public function addOnceEventListener(eventType:String,listener:Function):void 
    { 
     var f:Function = function(e:Event):void 
     { 
       this.removeEventListener(eventType,f); 
       listener(e); 
      } 
      this.addEventListener(eventType,f); 
    } 
} 

public class Example extends OnceEventDispatcher 
{ 


} 

var ex:Example = new Example(); 
ex.addOnceEventListener(type, func); 
+0

Ich kann die Vererbung nicht verwenden, da AS3 keine Mehrfachvererbung zulässt, und die meisten meiner Klassen erweitern bereits eine andere. Ich dachte daran, diese Funktion in eine externe .as-Datei zu integrieren, die ich in alle meine Klassen aufnehmen würde, aber ich fragte mich, ob es eine schönere Möglichkeit gäbe, dies tatsächlich zu tun. –

+0

Ich könnte auch die Funktion der UIComponent Klasse direkt im Flex SDK hinzufügen; das würde mein Problem lösen, aber es ist noch hässlicher =/ –

1
functionadd.addEventListener(COMPLETE,functionremove); 

functionremove() 
{ 
    runevent(); 
    functionadd.removeEventListener(COMPLETE,functionremove); 
} 
function runevent() 
{ 
    trace('Hello'); 
}