tags:

views:

33

answers:

1

Hello there,this seems to be an interesting question to be discovered in Flex.

I registered a very simple button event listener in A.mxml:

<mx:Script><![CDATA[

import mx.controls.Alert;
public function Handler():void
    {
      Alert.show('click event occured');
    }
]]></mx:Script>


<mx:Button label="{resourceManager.getString('resources', 'button.startLab')}" 
        id="nextStepButton" click="Handler()" />

It works fine when clicking the button everytime. Now I want to have something interesting,that is,I want to capture this buttonClick Event in another mxml file,say B.mxml and do something in B.mxml instead of A.

I am bit stuck on this,hope you could give me some hint and help,thanks a lot.

+2  A: 

There are a number of approaches to this problem. The simplest (and least object-oriented) is to have A be aware of B, or vice versa. In that case you can just add a listener. In B you could say a.nextStepButton.addEventListener(MouseEvent.CLICK, myHandler), or in A you could do this.nextStepButton.addEventListener(MouseEvent.CLICK, b.myHandler). (When one component is instantiated, you have to set a reference to it on the other component.)

One step better would be to dispatch a custom event that bubbles, with one of the components still aware of the other. In B: a.addEventListener(CustomNavigationEvent.NEXT_CLICK, myHandler), or in A: b.addEventListener(CustomNavigationEvent.NEXT_CLICK, myHandler).

Taking it further, you could just let the event bubble to the top (the SystemManager) and add your listener to the SystemManager. This way B is not aware of A at all. In B: this.systemManager.addEventListener(CustomNavigationEvent.NEXT_CLICK, myHandler).

Taking it even further, you can implement your own version of an event broadcaster, which is just a third object that is accessible by any component, usually implemented as a singleton, that takes listener registrations and accepts event dispatches, then broadcasts that event to registered listeners.

Hope that helps.

EDIT: Here's some code for doing it the first way:

In A.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="onCreationComplete(event)">
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;

            public var b:B;

            private function onCreationComplete(e:FlexEvent):void {
                // Note that you have to have a public onClick handler in B
                this.myButton.addEventListener(MouseEvent.CLICK, b.onClick);
            }
        ]]>
    </fx:Script>
    <s:Button id="myButton"/>
</s:Group>

You need to make A aware of B in the container that declares instances of both A and B:

MXML:

<mypackage:A id="aComponent" b="bComponent"/>
<mypackage:B id="bComponent"/>

ActionScript equivalent:

        var aComponent:A = new A();
        var bComponent:B = new B();
        aComponent.b = bComponent;
Wade Mueller
Thanks Wade! very helpful.Since I am a very new beginner to Flex,I would like to adopt the first approach you suggested.Could you help me on where to put the this.nextStepButton.addEventListener(MouseEvent.CLICK,b.myHandler)Thanks a lot!
Robert
Added some code above to show how this can be implemented. There are several ways of doing this, this is just one. Hope that helps.
Wade Mueller
Thanks a lot,Wade!
Robert
Sorry Wade,I got complaints aboutthis.nextStepButton.addEventListener(MouseEvent.CLICK, b.myFunction());says: "1067: Implicit coercion of a value of type void to an unrelated type Function."myFunction() is the public event handler that I wrote in B.Do you know where I got wrong?Thanks
Robert
You need to leave the parentheses off of the handler parameter in addEventListener. Leave it as b.myFunction
Wade Mueller
Hi Wade,I put it like:<mypackage:Radioactivitiy_Lab_Client id="aComponent" b="bComponent"/>Got complains"The prefix "mypackage" for element mypackage:Radioactivitiy_Lab_Client" is not bound. "Sorry for troubling you again
Robert
That's an example namespace, you'll need to change that to whatever namespace you have declared in your MXML for your components. Flash Builder will do this for you automatically if you just start typing the "less than" symbol and the first few letters of your component name. Then when you choose the suggested component, the appropriate namespace will automatically get added to your file.
Wade Mueller