6 Replies Latest reply on Jul 10, 2007 8:07 AM by toddmz2

    Multiple components listen to the same custom event?

    toddmz2 Level 1
      I've been trying to make the transition from Flash to Flex and I've been struggling with this one for the past two days. I used to do a lot of _root.moviecontainer.mylable.text referencing, but I'm trying to get the idea of events, dispatchevents, etc. down and be able to pass the referencing to flex to handle. The simple explanation of what I'm trying to do is to have a component trigger an event and to have it dynamically broadcast to any and all components that subscribes to that event (the number of components listening will change during run-time and I therefore don't want to directly reference those objects). I would like to be able to dynamically generate other objects during run-time and associate them to this event. I've been trying to add an addListener(customEvent) to listen for the dispatchevent(), but I've had no luck with this method so far. The event is firing, but I can't figure out how to associate other components with it. I imagine this having just three parts to it: the component that triggers the event, the event itself (custom), and the component that is listening for the event. And none of the components know anything of any of the other components that exist. The trigger component could be firing an event that 3, 10, or 100, other components are listening to, but it doesn't know how many components are listening, nor does it care & likewise the listening component might be waiting for a single component that's capable of firing of the event it's listening for or there might be a total of 10 components that are capable of firing off this event. If you made it to the end of this, I thank you. This has been such a headache for me and I'd really appreciate any and all help offered. Thanks.
        • 1. Re: Multiple components listen to the same custom event?
          ntsiii Level 3
          I think you will want to pay close attention to the "bubbles" property. Assuming the listener is in the document chain, and the event is set to bubble, you can listen anywhere, and it does not matter who is the dispatcher. "target" or currentTarget will tell the handler who dispatched the event.

          The full event architecture/functionality is pretty complex. There are several phases, including the capture and bubble pahse. Read those docs. I have, several times, and I do not pretend to understand it completely, but have been able to muddle through so far.

          In any event, the event dispatcher never knows anything about the listeners. It is always the listener component's responsibility to subscribe to an event.

          You can create and remove listeners dynamically at run time. I've not dome much of this myself.

          Tracy
          • 2. Re: Multiple components listen to the same custom event?
            toddmz2 Level 1
            Yah, I've looked into bubbling, but I don't understand how it all works if you need to go up the chain and back down another one. Can you go up one chain back to the root and down others looking for listeners? I've searched and searched and just can't find any tutorials or examples that (to me) appear to address this topic. Thanks.
            • 3. Re: Multiple components listen to the same custom event?
              ntsiii Level 3
              At the simplest core, when you dispatch an event like this:
              dispatchEvent(new Event("mycustomevent",true));
              the "true" in the second paremater specifies the event should bubble.

              You can now listen for that event from anything in the dispatching components parent chain, like Application at the top.

              Tracy
              • 4. Re: Multiple components listen to the same custom event?
                toddmz2 Level 1
                Tracy, first off I want to thank you again for taking the time to help me, but unfortunately something still isn't clicking for me. Here's a very simple app that I'm experimenting with trying to get it to work:

                main.mxml:

                <?xml version="1.0" encoding="utf-8"?>
                <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="absolute" xmlns:UI="com.ui.*" >

                <UI:iButton/>
                <UI:iTextArea x="50"/>

                </mx:Application>

                CustomEvent.as:

                package com.event
                {
                import flash.events.Event;

                public class CustomEvent extends Event
                {
                public function CustomEvent( type:String )
                {
                super(type, true); //So, it should be bubbling, correct?
                }

                override public function clone():Event
                {
                return new CustomEvent( type );
                }
                }
                }

                iButton.as

                package com.ui
                {
                import mx.controls.Button;
                import com.event.*;
                import flash.events.MouseEvent;

                public class iButton extends Button
                {
                public function iButton():void
                {
                super();

                this.addEventListener( "click", doThis );
                this.addEventListener( "somethingJustHappened", callbackFunc );
                }

                public function doThis( event:MouseEvent ):void
                {
                trace( "button clicked" );
                this.dispatchEvent( new CustomEvent( "somethingJustHappened" ));
                }

                public function callbackFunc( event:CustomEvent ):void
                {
                trace( "button event listener triggered" );
                }
                }
                }

                iTextArea.as

                package com.ui
                {
                import mx.controls.TextArea;
                import com.event.*;

                public class iTextArea extends TextArea
                {
                public function iTextArea():void
                {
                super();

                this.addEventListener( "somethingJustHappened", callbackFunc ); //This never gets triggered.
                }

                public function callbackFunc( event:CustomEvent ):void
                {
                trace( "textarea event listener triggered" );
                }
                }
                }

                Here's the output from the trace statements from when I press the button:

                button clicked
                button event listener triggered

                I'm sure my mistake is simple and probably stupid, but if you would be so kind as to help me figure it out, I'd really appreciate it. Thanks.
                • 5. Re: Multiple components listen to the same custom event?
                  ntsiii Level 3
                  iTextArea is a sibling of iButton and is not in its parent chain, so it won't get a bubbled event.

                  Perhaps you could put a handler in Application that re-dispatches the events and listen for them in iTextArea.

                  Tracy
                  • 6. Re: Multiple components listen to the same custom event?
                    toddmz2 Level 1
                    That did the trick. Thank you so very much!