简体   繁体   中英

adding functionality to nested components

OK Here's the situation...

I have a custom mxml component that contains a couple of images and 4 buttons. The component file already contains a clickHandler for each of the buttons. I need to be able to either access the clickHandler or create another function and attach it to those buttons from within my Main.mxml file. Should I add to the original clickHandlers ? if so, how do I apply the method to my Main.mxml file?

FYI: The component has 5 states and each clickHandler triggers transitions between the states.

Here are the two clickHandlers from the component file:

protected function submit_clickHandler():void
        {
            const state:String = currentState;
            if ( state == 'state1' ) {
                currentState='state2';
            }
            if ( state == 'state3' ) {
                currentState='state4';
                addElement(images[i]);     //The methods I want to run from 
                getStudentAnswer();        //within the Main.mxml.
                submit();                  //If I add them here, I get an
                newQuestion();             //undefined method error.
            }
            if ( state == 'state4' ) {
                currentState='state4';
            }
            if ( state == 'state5' ) {
                currentState='state4';
            }
            if ( state == 'state3' ) {
                Sequence1.play();
            }
        }

        protected function checkAnswer_clickHandler():void
        {
            const state:String = currentState;
            if ( state == 'state2' ) {
                currentState='state1';
            }
            if ( state == 'state4' ) {
                currentState='state5';
            }
        }

Thanks, JM

If you have access to the dispatch event for the buttons, just set "bubbles" to "true" and listen for the event in Main.mxml. If you think of the display list as a hierarchal tree with branches, an event that bubbles will travel up the branch until it reaches the first DisplayObject. Along the way, it checks each DisplayObject to find if it is waiting to capture the event.

Here is a basic illustration where Main is listening for a click event and has a child MovieClip instance with a child Sprite instance. The Sprite instance has a child Button instance that is dispatching a click event.

[object Main] (listening for MouseEvent.CLICK)
      |
      |__[object MovieClip]
                |
                |___[object Sprite]
                          |
                          |____[object Button] (dispatching MouseEvent.CLICK)

The dispatched click event in Button would be:

dispatchEvent(new MouseEvent(MouseEvent.CLICK, true));

In Main, you would just listend for the event:

addEventListener(MouseEvent.CLICK, clickHandler);

Because MouseEvent.CLICK is such a common event, I would suggest creating a custom event (or at least a unique event name) in this type of scenario to avoid the possibility of DisplayObject's capturing incorrect events. But, hopefully this gives a better idea of how to handle bubbling.

-

Without bubbling, the only other way to capture the event would be to use dot syntax. I don't recommend this method because it could get messy, but this helps to illustrate the concept of bubbling (assuming each child DisplayObject is public):

In Main: (again, not recommended)

movieClip.sprite.button.addEventListener(MouseEvent.CLICK, clickHandler);

Hope that helps!

[EDIT - Added custom Event] Here is what a custom Event class would look like:

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

    public class CustomEvent extends Event {

        public static const WITH_DATA:String = "withData";

        public var data:Object;

        public function NavEvent(type:String, data:Object=null, bubbles:Boolean=false, cancelable:Boolean=false) {
            super(type, bubbles, cancelable);
            this.data = data;
        }
    }
}

You would then dispatch an event like:

var myString:String = "buttonState";
dispatchEvent(new CustomEvent(CustomEvent.WITH_DATA, myString, true));

And listen for the event like:

addEventListener(CustomEvent.WITH_DATA, customEventHandler);

private function customEventHandler(e:CustomEvent):void {
    trace(e.data);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM