Добавление функциональности во вложенные компоненты

Хорошо, вот ситуация...

У меня есть пользовательский компонент mxml, который содержит пару изображений и 4 кнопки. Файл компонента уже содержит clickHandler для каждой из кнопок. Мне нужно иметь возможность получить доступ к clickHandler или создайте другую функцию и прикрепите ее к этим кнопкам из моего Main.mxml файл. Должен ли я добавить к оригиналу clickHandlers? если да, то как мне применить метод к моей Main.mxml файл?

К вашему сведению: компонент имеет 5 состояний и каждый clickHandler запускает переходы между состояниями.

Вот два clickHandlers из файла компонента:

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';
            }
        }

Спасибо JM

1 ответ

Решение

Если у вас есть доступ к событию отправки для кнопок, просто установите для "bubbles" значение "true" и прослушайте событие в Main.mxml. Если вы рассматриваете список отображения как иерархическое дерево с ветвями, событие, которое всплывет, будет перемещаться вверх по ветви, пока не достигнет первого объекта DisplayObject. Попутно он проверяет каждый DisplayObject, чтобы определить, ожидает ли он захвата события.

Вот базовая иллюстрация, где Main прослушивает событие click и имеет дочерний экземпляр MovieClip с дочерним экземпляром Sprite. Экземпляр Sprite имеет дочерний экземпляр Button, который отправляет событие click.

[объект Main] (прослушивание MouseEvent.CLICK)
      |
      |__[объект MovieClip]
                |
                |___[объект Sprite]
                          |
                          |____[кнопка объекта] (отправка MouseEvent.CLICK)

Отправленное событие click в Button будет:

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

В Main вы просто хотели бы посетить мероприятие:

addEventListener (MouseEvent.CLICK, clickHandler);

Поскольку MouseEvent.CLICK является таким распространенным событием, я бы предложил создать пользовательское событие (или, по крайней мере, уникальное имя события) в этом типе сценария, чтобы избежать возможности захвата некорректных событий DisplayObject. Но, надеюсь, это даст лучшее представление о том, как справиться с пузырями.

-

Без пузырей, единственный другой способ захватить событие - это использовать точечный синтаксис. Я не рекомендую этот метод, потому что он может запутаться, но это помогает проиллюстрировать концепцию пузырьков (при условии, что каждый дочерний DisplayObject является открытым):

В основном: (опять же, не рекомендуется)

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

Надеюсь, это поможет!

[EDIT - Добавлено пользовательское событие] Вот как будет выглядеть пользовательский класс Event:

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;
        }
    }
}

Затем вы бы отправили событие как:

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

И слушать событие как:

addEventListener(CustomEvent.WITH_DATA, customEventHandler);

private function customEventHandler(e:CustomEvent):void {
    trace(e.data);
}
Другие вопросы по тегам