Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

remove a listener that has an anonymous function in Actionscript 3

up.addEventListener(MouseEvent.CLICK, 
    function clickFunc(event:MouseEvent):void
    { 
        revealSpinner(event,51.42,1,spinner);
        event.currentTarget.removeEventListener(event.type, arguments.callee);
        autoTimer.stop();
    },
    false, 0, true);
down.addEventListener(MouseEvent.CLICK, 
    function clickFunc(event:MouseEvent):void
    { 
        revealSpinner(event,51.42,-1,spinner);
        event.currentTarget.removeEventListener(event.type, arguments.callee);
        autoTimer.stop();
    },
    false, 0, true);

The above code adds a listener to a couple of MC's. Originally the methods were anonymous but I have named them clickFunc() in order to try an reference them in my remove listener.

Here is my remove listener code. Both of these snippets are in separate functions. The add listener method is called before the remove method.

up.removeEventListener(MouseEvent.CLICK, clickFunc );
down.removeEventListener(MouseEvent.CLICK, clickFunc);

As soon as I publish the movie I get this error:

1120: Access of undefined property clickFunc.
like image 415
ed209 Avatar asked Jan 06 '10 12:01

ed209


1 Answers

First of all, you have the same name used twice (clickFunc), it cannot be inferred which one you refer to in your calls to removeEventListener. Second of all, clickFunc will only be accessible in the function where it is declared:

function foo() {
    var clickFunc: Function;
    up.addEventListener(MouseEvent.CLICK, 
        clickFunc = function (event:MouseEvent):void
        { 
            revealSpinner(event,51.42,1,spinner);
            event.currentTarget.removeEventListener(event.type, arguments.callee);
            autoTimer.stop();
        },
        false, 0, true);

    // 'clickFunc' available here, so this is possible:
    up.removeEventListener(MouseEvent.CLICK, clickFunc);
}

function bar() {
    // 'clickFunc' is not available here, so this is not possible:
    up.removeEventListener(MouseEvent.CLICK, clickFunc);
    // 1120: Access of undefined property clickFunc
}

If you need to reference the methods (like, say, removing them from an event), they can't be anonymous. If you need to reference them from several methods, then they shouldn't be local to one method (foo in the example above). And they need different identifiers (clickFunc1 and clickFunc2 if you will). This is my suggested solution:

private function addHandlers(): void
{
    up.addEventListener(MouseEvent.CLICK, upClickHandler, false, 0, true);
    down.addEventListener(MouseEvent.CLICK, downClickHandler, false, 0, true);
}

private function removeHandlers(): void
{
    up.removeEventListener(MouseEvent.CLICK, upClickHandler);
    down.removeEventListener(MouseEvent.CLICK, downClickHandler);
}

private function upClickHandler(event:MouseEvent):void
{ 
    revealSpinner(event,51.42,1,spinner);
    event.currentTarget.removeEventListener(event.type, arguments.callee);
    autoTimer.stop();
}

private function downClickHandler(event:MouseEvent):void
{ 
    revealSpinner(event,51.42,-1,spinner);
    event.currentTarget.removeEventListener(event.type, arguments.callee);
    autoTimer.stop();
}

Of course, if, like in your example, the methods are identical you can use only one:

private function addHandlers(): void
{
    up.addEventListener(MouseEvent.CLICK, clickHandler, false, 0, true);
    down.addEventListener(MouseEvent.CLICK, clickHandler, false, 0, true);
}

private function removeHandlers(): void
{
    up.removeEventListener(MouseEvent.CLICK, clickHandler);
    down.removeEventListener(MouseEvent.CLICK, clickHandler);
}

private function clickHandler(event:MouseEvent):void
{ 
    revealSpinner(event,51.42,-1,spinner);
    event.currentTarget.removeEventListener(event.type, arguments.callee);
    autoTimer.stop();
}
like image 157
Markus Johnsson Avatar answered Oct 03 '22 23:10

Markus Johnsson