Is there a way to remove listeners easier?

2019-08-16 05:37发布

问题:

so, there´s a easy way to remove all childs from container like this

while (container.numChildren)
{
    container.removeChildAt(0);
}

is there a way to remove stage.eventListener in plural (dont know if im using the word right), something like stage.eventListeners? something like that?

thanks!

回答1:

No, there isn't. There is no mechanism, at least publicly available, that keeps track of event listeners. However, you could do it yourself.

Basically, you need to keep track of each listener that is added. The easiest way would be to extend the classes you want to do this on and override addEventListener().

private var listeners:Vector.<Object>;

override public function addEventListener( type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false ):void {
    var obj:Object = {
        type : type,
        listener : listener
    };
    this.listeners.push( obj );
    super.addEventListener( type, listener, useCapture, priority, useWeakReference );
}

override public function removeEventListener( type:String, listener:Function, useCapture:Boolean = false ):void {
    var i:Number, l:Number;
    l = this.listeners.length;

    for ( i = 0; i < l; i++ ) {
        if ( this.listeners[i].type == type && this.listeners[i].listener == listener ) {
            this.listeners.splice( i, 1 );
            break;
        }
    }

    super.removeEventListener( type, listener, useCapture );
}

public function removeAllEventListeners():void {
    var i:Number, l:Number;
    l = this.listeners.length;

    for ( i = 0; i < l; i++ ) {
        super.removeEventListener( this.listeners[i].type, this.listeners[i].listener );
    }
    this.listeners.splice( 0, this.listeners.length ); //empties the vector
}

If extending a class is not an option for you (either because you are using Flash Pro with the timeline or if it's the stage you need to remove all event listeners from), you could manually add it to the Vector each time you add an event listener. It's not quite as simple as the way I described above, but it would still work.

Do note that you should probably add the useCapture property to the object that is being saved and check for that as well, but I have honestly never set that property to anything but default so I did not include it in my code



回答2:

In FlashPlayer 11, DisplayObjectContainer supports a removeChildren function that removes all children. So you can replace your while loop with container.removeChildren()

As for removing all eventListeners, there is no built-in method for this. However, you could write something yourself to keep track of all listeners added to a particular object, allowing you to remove them all by looping over the collection.



回答3:

Unfortunately the short answer is that it is not possible. Per default, event dispatchers do not publically keep track of what listeners are registered. So you cannot loop over some list and just remove them all.

You will have to remember the listeners you add yourself.



回答4:

There is a very easy solution, Robert Penner's phenomenal Signals library. Here is an example:

import org.osflash.signal.Signal;

public class Rocket()
{
    //  Signals are used to dispatch messages to interested parties
    public var enginesFiredSignal:Signal;
    public function Rocket()
    {
        //  You have to instantiate the signal for it to do anything
        enginesFiredSignal = new Signal();
    }

    public function fireEngines():void
    {
        //  Dispatch will notify any interested parties
        enginesFiredSignal.dispatch();
    }

    public function dispose():void
    {
        //  This is the magic call... it removes *all* interested parties.
        //  No need to iterate through them and removeEventListeners.
        enginesFiredSignal.removeAll();
    }
}

public class Academy()
{
    public var rocket:Rocket;
    public function Academy()
    {
        rocket = new Rocket();
        //  We are interested to know *when* the engines fire,
        //  so we "add" ourself to the Signal.
        rocket.enginesFiredSignal.add( enginesFiredHandler );
        //  This call will force the Signal to do its thing
        rocket.fireEngines();
        //  Disposing of the Rocket will automatically remove us from
        //  its Signal. No further event removal or maintenance required.
        rocket.dispose();
    }

    public function enginesFiredHandler():void
    {
        trace( "engines were fired" );
    }
}

You can go way beyond this to do parameter passing and all sorts of interesting things. I recommend you check out his blog.

http://flashblog.robertpenner.com

Here is a tutorial on how to get started with AS3 Signals:

http://www.youtube.com/watch?v=wB_sWJ5EgXI