AS3 Listener через экземпляры объекта - возможно / хорошо или плохо? - PullRequest
1 голос
/ 15 февраля 2010

У меня вопрос относительно слушателей as3 и экземпляров класса.

Основной вопрос: есть ли способ отправить событие из экземпляра кнопки таким образом, чтобы другие экземпляры кнопки могли прослушивать (без необходимости прослушивателя в классе документа)

Допустим, у меня есть класс документа и класс кнопки. В документе будет несколько экземпляров класса кнопки, добавленных в список отображения. Когда кнопка выбрана, вызывается метод set для установки переменной пакета выбранного для этого экземпляра. Именно отсюда я хотел бы отправить событие, чтобы уведомить все остальные экземпляры.

|document
|-button instance 1
|-button instance 2
|-button instance 3 (i want to send an event directly to instance 1 and 2...)

Мое текущее решение состояло в том, чтобы создать класс buttonGroup, который бы создавал экземпляры кнопок, и кнопки отправляли бы вызов события родительскому элементу группы.

|document
|-button group (catch the event and send an event to all instances within the group)
|---button instance 1
|---button instance 2
|---button instance 3 (dispatch  the event)

Но моя проблема осталась - если бы у меня было несколько групп, и я хотел отправить событие всем экземплярам группы ... тогда мне понадобился бы класс buttonManager для отслеживания групп (или, по крайней мере, так я понимаешь?)

|document
|-button manager (catch the event and send an event to all group instances)
|
|---button group 1
|-----button instance 1
|-----button instance 2
|-----button instance 3 (dispatch  the event)
|
|---button group 2
|-----button instance 1
|-----button instance 2
|-----button instance 3 (dispatch  the event)

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

Надеюсь, это было достаточно наглядно, и будьте осторожны, я новичок в ООП ... Заранее спасибо.

document.as

import flash.display.*;
import flash.events.*;
import myClasses.events.ButtonEvent;

public class Document extends MovieClip {       

    public function Document(){
        trace("initialising Document...");
        addEventListener(Event.ADDED_TO_STAGE, popStageVars);           
    }   


    private function popStageVars(e:Event){
        trace("popping stage vars...")

        var ob1:AbstractOBJ = new AbstractOBJ           
        var ob2:AbstractOBJ = new AbstractOBJ           
        var ob3:AbstractOBJ = new AbstractOBJ

        addChild(ob1)
        addChild(ob2)
        addChild(ob3)


        ob1.selected = ob1
        ob2.selected = ob2
        ob3.selected = ob3

    }       

}

Класс кнопок:

import flash.display.*; 
import flash.events.*;
import myClasses.events.ButtonEvent;

public class ButtonOBJ extends MovieClip  implements IEventDispatcher {

    internal static var _selected:Object = null

    public function ButtonOBJ(){
        trace("initialising ButtonOBJ...");         
        addEventListener(Event.ADDED_TO_STAGE, popStageVars);
        addEventListener(AbstractEvent.SET_CUR, checkClip);
    }


    private function popStageVars(e:Event){
        trace("popping stage vars..." + this.name)
    }       

    private function checkClip(e:AbstractEvent){
        trace("checking button registered... " + this.name)
    }

    public function get selected():Object{
        return _selected                        
    }

    public function set selected(s:Object):void{
        var sName:String 

        if(selected != null){
            sName = selected.name
        }else{
            sName = null
        }

        trace(this.name + " is changing the current selected from: " + sName + " - to: " + s.name)          

        _selected = s
        dispatchEvent(new AbstractEvent(AbstractEvent.SET_CUR, true));  
    }       

}

, а также кнопка Event:

package myClasses.events{       

import flash.events.Event;

public class ButtonEvent extends Event {

    public static const SET_CUR:String = "setSelected";
    public static const VERSION:Number = 1.0;

    public function ButtonEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false) {         
        super(type, bubbles, cancelable);
    }

    public override function clone():Event {
        return new ButtonEvent(this.type, this.bubbles, this.cancelable);
    }   

}
}

Ответы [ 2 ]

1 голос
/ 15 февраля 2010

Ваш класс кнопки может добавить слушателя на сцену. Если ваше событие вспыхивает, когда событие запускается целью, оно всплывает на сцену. Кнопка «услышит» событие и ответит. Я обычно делаю то, что вы делаете, хотя и добавляю слушателя в группу. Затем я зацикливаюсь на кнопках при получении события и устанавливаю «выбранный», если event.target совпадает с текущей кнопкой в ​​цикле.

0 голосов
/ 17 апреля 2014

Также относительно новый для AS3, но я много работал со слушателями событий в последнее время. Проблема с добавлением слушателя события на сцену заключается в том, что он будет срабатывать каждый раз, когда событие попадает на сцену. Кроме того, если прослушиватель событий является частью класса, и вы добавили 10 экземпляров этого класса, на сцене теперь будет 10 прослушивателей событий, которые будут делать одно и то же, и все они будут запущены. Если вы хотите дифференцировать (каждая кнопка АКА делает что-то свое), вам все равно придется их циклически проходить, и это лишает смысла попытки добавить ее на сцену.

Что я делал, так это не использовал прослушиватели событий для чего-либо, кроме пользовательских событий в моих объектах нижнего уровня. Допустим, у меня есть три кнопки, которые я хочу делать по-разному, когда они (и только они) нажаты. Ну, для того, чтобы вообще появиться, их нужно добавить как детей чего-то, верно? Я добавляю прослушиватель одного события к тому, кем является их родитель, а затем вызываю функцию, которую я хочу вызвать из родительского объекта. Вот так:

(Примечание: это больше псевдокод, чем фактический код)

public class ParentObject extends Sprite{
    public ParentObject(){
        addchild(new ButtonObject1());
        addchild(new ButtonObject2());
        addchild(new ButtonObject3());
        addEventListener(MouseEvent.CLICK, doButtonThing);
    }

    private doButtonThing(e:MouseEvent):void{
        if(e.target is ButtonObject){
            e.target.doStuff();
        }
    }
}

public ButtonObject1 extends ButtonObject{ //This works for 2 and 3. Also note that all three objects extend a parent class called ButtonObject. This is useful in checking the event target.
    public ButtonObject1(){
        //Create the Object here.
    }

    public doStuff():void{
         //Whatever you want the button to do
    }

}

Когда что-то нажимается, родительский объект будет ловить событие. Затем он проверит, был ли объект, по которому щелкнули, ButtonObject (1, 2 или 3; мы не хотим, чтобы что-то запускалось, если это не кнопка). Если это так, он вызывает функцию doStuff в той, по которой щелкнули, а не в других. Вам не нужно явно отслеживать их, так как он использует event.target для поиска объекта. Вы также предотвращаете одновременное срабатывание всех кнопок, и, конечно, они могут делать разные вещи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...