2010-02-15 3 views
1

J'ai une question concernant les écouteurs as3, et les instances d'une classe.AS3 Listener sur les instances d'objets - possible/bonne ou mauvaise pratique?

La principale question: est-il possible d'envoyer un événement de l'instance de bouton de telle sorte que les autres instances de bouton peuvent écouter (sans la nécessité d'un auditeur dans la classe de document)

permet de dire que je avoir une classe de document et une classe de bouton. Le document aura plusieurs instances de la classe de boutons ajoutées à la liste d'affichage. Lorsqu'un bouton est sélectionné, la méthode set est appelée pour définir la variable package de selected sur cette instance. C'est d'ici que je voudrais envoyer un événement pour notifier toutes les autres instances. solution

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

Mon actuelle était de créer une classe buttonGroup, qui a instancié les boutons et les boutons enverrait un appel d'événement au parent du groupe.

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

Mais mon problème est resté - si j'avais plusieurs groupes et je voulais envoyer un événement à tous de l'instance de groupe .. alors je aurais besoin d'une classe buttonManager pour garder la trace des groupes (ou au moins, c'est comment je comprends?)

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

Je ne suis pas défavorable à ces « solutions », je suis juste curieux de savoir s'il y a une autre façon, ou si, en fait, mes solutions sont une bonne pratique. La base de mon code se trouve ci-dessous (moins le gestionnaire de bouton et les classes de groupe)

J'espère que c'était assez descriptif, et être doux, je suis nouveau à OOP ... Merci d'avance.

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 

    }  

} 

La classe bouton:

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

} 

et aussi le 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); 
    } 

} 
} 

Répondre

1

Votre classe bouton pourrait ajouter un écouteur à la scène. Si votre événement se déclenche, lorsque l'événement est déclenché par la cible, il se propage jusqu'à la scène. Le bouton "entend" l'événement et répond. En général, je fais ce que vous faites et j'ajoute l'auditeur à un groupe. Ensuite, je fais une boucle sur les boutons lorsque l'événement est reçu et réglé sur "sélectionné" si le event.target est le même que le bouton actuel dans la boucle.

+0

Si je comprends bien - vous dites ajouter un écouteur à la classe de document - mais les boutons n'entendent pas parce que l'événement bouillonne vers le haut, et ne frappe jamais les autres instances - à moins que je me trompe. Le problème que j'ai avec cette approche: il me force à garder une trace de tous les boutons créés (un tableau, en passant par les appels de méthode d'envoi aux instances), et perd l'approche auto-consciente im recherche. Cette voie est essentiellement la même que le groupe. Id aime garder toute la gestion des boutons loin de la classe de document ... Si j'ai mal compris, cela vous dérangerait-il d'élaborer? – Beans

+0

Pas la classe de document, mais la scène. stage.addEventListener(); serait à l'intérieur de votre classe de bouton. – typeoneerror

+0

Forrest pour les arbres hein? Je vous remercie. Je sens l'homme qui a perdu ses lunettes pour les trouver sur sa tête. En note de bas de page - ajouter un écouteur de scène de cette façon, est-ce considéré comme une mauvaise forme par rapport à la méthode de groupe et de gestionnaire? – Beans

0

Aussi relativement nouveau à AS3, mais j'ai fait beaucoup avec les auditeurs d'événements récemment. Le problème avec l'ajout d'un écouteur d'événement à la scène est qu'il se déclenchera à chaque fois que cet événement atteindra la scène. De plus, si l'écouteur d'événement fait partie d'une classe et que vous ajoutez 10 instances de cette classe, la scène va maintenant avoir 10 auditeurs d'événements qui font tous la même chose, et ils vont tous tirer. Si vous voulez de la différenciation (AKA chaque bouton fait quelque chose de différent), vous devrez les boucler de toute façon et cela va à l'encontre de l'objectif d'essayer de l'ajouter à la scène.

Ce que j'ai fait n'utilise pas d'écouteurs d'événements pour autre chose que des événements personnalisés dans mes objets de niveau inférieur. Disons que j'ai trois boutons que je veux faire des choses différentes quand ils (et seulement eux) sont cliqués. Eh bien, pour apparaître, ils vont devoir être ajoutés comme enfants de quelque chose, n'est-ce pas?J'ajoute un seul écouteur d'événement à n'importe quel parent, puis j'appelle la fonction que je veux avoir du parent. Comme si:

(Note: Ceci est plus que le code pseudo-code réel)

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 
    } 

}

Quand quelque chose est cliqué, l'objet parent va attraper l'événement. Ensuite, il vérifiera si l'objet sur lequel vous avez cliqué était un ButtonObject (1, 2 ou 3, nous ne voulons pas que quelque chose se déclenche si ce n'est pas un bouton). Si c'est le cas, il appelle la fonction doStuff dans celui qui a été cliqué et pas les autres. Vous n'avez pas à les suivre explicitement, car il utilise event.target pour trouver l'objet. Vous empêchez également tout le bouton de tirer à la fois, et bien sûr, ils peuvent tous faire des choses différentes.

Questions connexes