9 Replies Latest reply on Dec 20, 2006 10:24 AM by tombenson

    problem catching events from a different component

    tombenson
      So, I'm probably dumb, and I've read and gone through all the examples, and I still can't get this to work:
      In my main mxml file, i have a view stack, which is consists of mxml components (based on the Canvas) that i have in a subfolder.
      I created a custom event which is dispatched from a control on the main form (to change the language that displays throughout the app). The events dispatch correctly, because I can catch them from within the main file, but I can't catch them from within the components...
      What am I doing wrong? Am I not adding the listener in the right place? (I've tried numerous things, including this.addEventListener(...) from within the component.
        • 1. Re: problem catching events from a different component
          FlightGuy Level 1
          I'm not sure because you're not telling us where you have put the listener, but I'll take a guess and if I'm wrong you can give us some more detail.

          As I understand, you have an mx:Application that hosts multiple controls. One of these controls allows a user to select a language, and upon change dispatches an event. You have added a listener in the Application that is successfully being fired, but you want to listen for this event in the other child components.

          You need to think carefully about what you're attaching the listener to, because you'll only receive the events if you're listening on the same thing that's dispatching the events.

          If you're receiving the event in the application, you could re-dispatch the event from the application and listen for it in the child components. Alternatively you could set bubbling to true on your event - then you can listen for it on any of the parents.
          • 2. Re: problem catching events from a different component
            tombenson Level 1
            Ah, ok. I'll try redispatching an event from the application. Here's how I have it structured:
            Mockup project folder
            Mockup.mxml
            Custom folder
            LaguageEvent.as
            MainViews folder
            SetupView.mxml

            The custom event is declared in LanguageEvent.as, and is dispatched as a result in the change of a popupListButton control in Mockup.mxml. I tried it with bubbling both on and of, but... so events only "bubble up", i.e. from the button control up to the application, but not back down the other child nodes? If I attach a listener to the application, then use that to redispatch the event, all the children should see it?
            • 3. Re: problem catching events from a different component
              tombenson Level 1
              (doh, sorry. apparently you can't indent in this thing, so my structure explanation sort of sucks.)
              • 4. Re: problem catching events from a different component
                FlightGuy Level 1
                If it bubbles you should be able to listen for it on the Application, even without redispatching it. BTW the layout of your source has no bearing on how any of your events propagate - just the parent-child relationships at runtime.
                • 5. Re: problem catching events from a different component
                  tombenson Level 1
                  But if I want to listen to it in a "sibling" node, then it would have to be redispatched from the parent?
                  • 6. Re: problem catching events from a different component
                    FlightGuy Level 1
                    Nope - if you listen on the Application, you'll be notified of the bubbly event irrespective or who you are. Once again, who you are has no bearing what events you'll receive or not. It's who you're listening to that matters.

                    So if I have a component <ns1:foo>, and inside foo there is a line of script that does something like this:

                    dispatchEvent(new Event('bubblyEvent', true); // second parameter is bubbles

                    Then I have an application that looks like this:

                    .<mx:Application ...>
                    . <mx:Script>
                    . private function initialize(event:Event):void{
                    . addEventListener('bubblingEvent', sayHi);
                    . }
                    . private function sayHi(event:Event):void{
                    . Alert.show('Hi');
                    . }
                    . </mx:Script>
                    . <ns1:foo id="foo"/>
                    . <ns1:bar/>
                    .</mx:Application>

                    When foo fires its event the application will say Hi, even though the application is listening to itself. If the event is not a bubbling event, the application would need to do this:
                    . foo.addEventListener('unbublingEvent', sayHi);

                    In this example, bar could also implement a listener like this:
                    . (Application.application as IEventDispatcher).addEventListener('bubblingEvent', sayHi);

                    This would be fired even though the Application is not explicitly dispatching the event. By setting bubbles=true, it's sort of like dispatching the event from every component up the hierarchy. The difference is that when we listen to the application for a bubbling event dispatched by foo, event.target will refer to foo, and event.currentTarget will refer to the application.

                    Tim
                    • 7. Re: problem catching events from a different component
                      tombenson Level 1
                      I hate to post again, but maybe i'm just too dense. Let's say I have an application
                      APP. Inside the application there are two custom components (based on mx:canvas), C1, and C2. In C1, there is a button that does a
                      dispatchEvent(new Event('yada', true));
                      In C2, there is a component (or C2 itself) with an event listener
                      addEventListener('yada', dosomething);
                      And in APP, there is another
                      addEventListener('yada', dosomethingelse);

                      The listener in APP works fine, but for the life of me, I can't see how to dispatch an event from within C1, and catch it from within C2. Is it not possible? I can always catch it in APP and do what needs to be done, but it makes for less clean code... I wanted C2 to be more self-contained.
                      • 8. Re: problem catching events from a different component
                        FlightGuy Level 1
                        That's right - you can't do it because there's no such thing as 'sibling bubbling'. Bubbling goes up to the very top level, and that's it. That is why C2 never receives the event. The relevant thing is that C2 doesn't need to receive the event itself, because C1 and C2 share a common parent: The Application.

                        So C2 needs to list on the application, not on itself. Try on C2 doing this:
                        (Application.application as IEventListener).addEventListener('yada', dosomething);

                        This code is inside C2, and the dosomething function is in C2, but the event is actually received by the application. You don't need to put any code in the application to make that happen.

                        Humor me and try it. You can add the event listener in C2's initialize event.

                        Tim
                        • 9. Re: problem catching events from a different component
                          tombenson Level 1
                          Good point, and it works.
                          What I was trying to do with it is use and event to globally inform every piece of the application to change which language it's displaying (since you can't change resource bundles at run time).
                          I guess I was thinking of something more like an "event broadcaster", though it's probably not a very efficient idea.
                          Thanks much for the help!