2010-02-15 4 views
1

У меня есть вопрос относительно as3 слушателей и экземпляров класса.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)); 
    }  

} 

, а также buttonEvent:

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

} 
} 

ответ

1

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

+0

Если я понимаю правильно - вы говорите, что добавьте слушателя в класс документа, но кнопки не будут слышать, потому что событие пузырится вверху и никогда не попадает в другие экземпляры - если только я не ошибаюсь. Проблема, с которой я сталкиваюсь: это заставляет меня отслеживать все созданные кнопки (массив, перебирать вызовы методом диспетчеризации в экземпляры) и теряет самонаблюдающий подход, который ищет. Этот способ по существу тот же, что и у группы. Id люблю держать все кнопки управления вдали от класса документа ... Если я неправильно понял, не могли бы вы продумать? – Beans

+0

Не класс документа, а сцена. stage.addEventListener(); будет внутри вашего класса кнопок. – typeoneerror

+0

Форрест для деревьев да? Спасибо. Я чувствую себя лжецом, который потерял очки только, чтобы найти их на макушке. Как сноска - добавление слушателя сцены таким образом, считается ли это плохой формой по сравнению с методом группы и менеджера? – Beans

0

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

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

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

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 для поиска объекта. Вы также предотвращаете одновременную стрельбу, и, конечно же, они могут делать разные вещи.

Смежные вопросы