добавление функциональности во вложенные компоненты - PullRequest
1 голос
/ 03 мая 2011

O.K. Вот ситуация ...

У меня есть пользовательский компонент 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 Ответ

1 голос
/ 04 мая 2011

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

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

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

Отправленное событие нажатия в кнопке будет:

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

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

addEventListener(MouseEvent.CLICK, clickHandler);

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

-

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

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

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