I have used the function below for various debugging purposes. But it might
be *slightly* more robust than assuming the name of the generated function.
You would use it something like this:

    <mx:Button click="trace('only once');
event.currentTarget.removeEventListener('click',
this[getStackFunctionName()])" />


But yeah, I don't really understand the use-case either, as I've never had a
need to do anything like this in any Flex app that I have built....


As a side note, it's not uncommon for listener functions to want to remove
themselves. And the ideal way to do that would be a removeCurrentListener()
method on the Event class, or on IEventDispatcher. Though it is not part of
the DOM L3 event spec, It would be quite straightforward to implement there.
Back when AS2 was not out-of-date, it used to bug the hell out of me when
I'd see code like removeEventListener("event", arguments.caller), removing
the Delegate instance.

Peter


package memorphic.utils
{

    /**
     * Returns the name of a function in the current callstack.
     * @param stackOffset uint 0 is current function, 1 is caller, 2 is
caller's caller etc..
     */
    public function getStackFunctionName(stackOffset:uint=0):String
    {

        var count:int = stackOffset + 2;
        var stackTrace:String;
        try {
            throw new Error();
        }catch(e:Error){
            stackTrace = e.getStackTrace();
        }

        var re:RegExp = /(?:at [^\/]+)[^\(]+/g;
        var stackLine:String;
        while(count--){
            stackLine = re.exec(stackTrace)[0];
        }

        var res:Object =
/at\s(?P<obj>[^\/]+)\/(?:(?P<ns>[^:]+)(?:::))?(?P<name>[^:]+)?/.exec(stackLine);

        var obj:String = res.obj;
        var ns:String = res.ns;
        var name:String = res.name;

        return name;
    }

}



On 9/17/07, Gordon Smith <[EMAIL PROTECTED]> wrote:
>
>    > It seems like he wants a one click handled event.
>
> I'd like to understand his use case. If you remove the click handler but
> leave the Button, you have a UI that makes no sense: a Button that can be
> clicked but doesn't do anything. If he's trying to prevent the user from
> repeatedly clicking the Button after its click handler starts
> doing something asynchronous, then disabling the Button is the right thing
> to do.
>
> But if for some reason he really needs to remove the listener and leave
> the Button, then you're correct that using addEventListener() to install it
> would be best.
>
> - Gordon
>
>  ------------------------------
> *From:* [email protected] [mailto:flexcompone
> [EMAIL PROTECTED] *On Behalf Of *Michael Schmalle
> *Sent:* Monday, September 17, 2007 11:40 AM
> *To:* [email protected]
> *Subject:* Re: [flexcomponents] Removing Events defined by MXML
>
>  He's mixing apples and oranges.
>
> It seems like he wants a one click handled event. Once it's clicked,
> remove the listener. It seems to me Firdosh that the correct way to
> implement the functionality of what you want is adding the event listener in
> AS in a script tag. Using the hack you mentioned is not necessary becasue
> you just need to add a couple lines of action script.
>
> Why go to this trouble?
>
> Peace, Mike
>
> On 9/17/07, Gordon Smith <[EMAIL PROTECTED]> wrote:
> >
> >    I'm trying to understand why you want to remove the event listener.
> >
> > - Gordon
> >
> >  ------------------------------
> > *From:* [email protected] [mailto:flexcompone
> > [EMAIL PROTECTED] *On Behalf Of *Firdosh Tangri
> > *Sent:* Monday, September 17, 2007 7:14 AM
> > *To:* [email protected]
> > *Subject:* Re: [flexcomponents] Removing Events defined by MXML
> >
> >   thanks gordon but say if I dont remove the instance , but just want
> > remove the event listener
> > the removeEventListener would not work....cause the function would kept
> > be called
> >
> > On 9/14/07, Gordon Smith <[EMAIL PROTECTED]> wrote:
> > >
> > >   > Therefore there will always be a reference to the object and GC
> > > would not collect it.
> > >
> > >  I think you misunderstand. When you write
> > >
> > >     <mx:Button id="myButton" click="onClick"/>
> > >
> > > you cause the Button instance (the dispatcher of the 'click' event) to
> > > have a reference to the Application instance (the listener for the 'click'
> > > event) and not the other way around. A dispatcher keeps a list of 
> > > listeners,
> > > but listeners do not remember the dispatcher that they registered with.
> > >
> > > If you were to do
> > >
> > >     removeChild(myButton);
> > >     myButton = null;
> > >
> > > the Button would be eligible for garbage-collection because
> > > the Application would no longer have any reference to it.
> > >
> > > But I doubt that you're dynamically removing components, so what kind
> > > of leak were you worried about anyway?
> > >
> > > - Gordon
> > >
> > >  ------------------------------
> > > *From:* [email protected] [mailto:[EMAIL PROTECTED]
> > > *On Behalf Of *Firdosh Tangri
> > > *Sent:* Friday, September 14, 2007 3:32 PM
> > > *To:* [email protected]
> > > *Subject: *Re: [flexcomponents] Removing Events defined by MXML
> > >
> > >
> > >
> > > Well because the callback function keeps getting called even when I
> > > try to remove the
> > > event listener
> > >
> > > <mx:Application>
> > >      <mx:Script>
> > >         <![CDATA[
> > >                   private function onClick():void{
> > >
> > >                        trace("click");
> > >                        myButton.removeEventListener(MouseEvent.CLICK ,
> > > onClick);
> > >
> > >                   }
> > >
> > >          ]]>
> > >         </mx:Script>
> > >
> > >         <mx:Button id="myButton" click="onClick" />
> > > </mx:Application>
> > >
> > > In the above example the onClick function keeps getting called and the
> > >
> > >
> > > myButton.removeEventListener (MouseEvent.CLICK , onClick);
> > >
> > > does not work.
> > >
> > > Therefore there will always be a reference to the object and GC would
> > > not collect it.
> > >
> > > cheers
> > > firdosh
> > >
> > >
> > > On 9/14/07, Gordon Smith <[EMAIL PROTECTED]> wrote:
> > > >
> > > >    I just want to mention...
> > > >
> > > > The name of the autogenerated event handler method for an MXML event
> > > > attribute is an undocumented implementation detail that is subject to 
> > > > change
> > > > without notice in future versions of Flex.
> > > >
> > > > Also, I'm curious what you're trying to accomplish by removing these
> > > > listeners.
> > > >
> > > > - Gordon
> > > >
> > > >  ------------------------------
> > > > *From:* [email protected] [mailto: [EMAIL PROTECTED]
> > > > *On Behalf Of *Firdosh Tangri
> > > > *Sent:* Friday, September 14, 2007 9:20 AM
> > > > *To:* [email protected]
> > > > *Subject:* Re: [flexcomponents] Removing Events defined by MXML
> > > >
> > > >   Hey Josh,
> > > >                thanks well I an working on a big project and a lot
> > > > of creation complete and other mxml defined events are there
> > > >
> > > > I used a hack to kill the eventlistener
> > > >
> > > > basically just did  a
> > > >
> > > > var comp:UIComponent = event.currentTarget as UIComponent;
> > > > comp.removeEventListener(MouseEvent.CLICK, Application.application
> > > > ["__btn_click"];
> > > >
> > > > so there is 2 underscore , the id of the component in this case
> > > > "btn" and then underscore again and then the event name , which is click
> > > > here
> > > >
> > > >
> > > > and that basically took care of the problem.
> > > >
> > > > cheers
> > > > firdosh
> > > >
> > > >
> > > > On 9/14/07, Josh Tynjala <[EMAIL PROTECTED] > wrote:
> > > > >
> > > > >   As far as I know, it's not possible to remove events of this
> > > > > type. The Flex compiler actually generates a function to wrap around
> > > > > whatever you call. You can see the exact code if you look at the 
> > > > > generated
> > > > > code using the -keep compiler argument, but it looks something like 
> > > > > this:
> > > > >
> > > > > private function someGeneratedFunctionName(event:MouseEvent):void
> > > > > {
> > > > >     //your code gets copied here
> > > > >     onClick();
> > > > > }
> > > > >
> > > > > You can get an idea of why when you think of the fact that the
> > > > > "event" parameter is available in your click="" attribute in the 
> > > > > MXML. You
> > > > > can either pass it to your function or ignore it completely. In
> > > > > ActionScript, when you use addEventListener instead, your function 
> > > > > must
> > > > > always accept an event parameter.
> > > > >
> > > > >
> > > > > Firdosh Tangri wrote:
> > > > >
> > > > >  hey all,
> > > > >             I was just wondering if i define an event by mxml like
> > > > > <mx:Button id="myBtn" click="onClick();") />
> > > > >
> > > > > and then try and remove it
> > > > >
> > > > > private function onClick():void{
> > > > >     trace("Click");
> > > > >     myBtn.removeEventListener(MouseEvent.CLICK, onClick);
> > > > > }
> > > > >
> > > > > it still keeps calling the function but if i add the event
> > > > > listener through as
> > > > >
> > > > > like
> > > > >
> > > > > myBtn.addEventListener (MouseEvent.CLICK , onClick);
> > > > >
> > > > > then it removes the call back function.
> > > > >
> > > > > thanks
> > > > > cheers
> > > > > firdosh
> > > > >
> > > > >
> > > > >
> > > > >
> > > > >
> > > >
> > >
> >
>
>
> --
> Teoti Graphix
> http://www.teotigraphix.com
>
> Blog - Flex2Components
> http://www.flex2components.com
>
> You can find more by solving the problem then by 'asking the question'.
>
>  
>

Reply via email to