2009-09-07 2 views
4

У меня есть один основной «родительский» swf, который загружает несколько других swf. Если что-то происходит в главном swf, мне нужно сообщить об этом одному из дочерних swf.as3 - dispatchEvent от родительского swf к дочернему swf

Это, похоже, хорошо работает наоборот. Любой из детей может просто dispatchEvent(), и я могу настроить основной swf для прослушивания события. Тем не менее, я не могу заставить дочерний swf поймать любые события, отправленные родителем. Как это делается?

ответ

5

ОК, так что, если вы уже знаете это уже, мои извинения ... но это кажется довольно распространенной проблемой и не сразу очевидна.

В событиях AS3, отправленных объектами в списке отображения, можно прослушать так, как они пузыряют до иерархию списка отображения, не указывая исходный объект. (Предполагая, конечно, что событие имеет свойство барботирования, равное true). Следовательно, класс документов (старая концепция _root) может реагировать на щелчки мыши с любого экранного объекта, независимо от того, насколько глубоко он вложен, с

addEventListener(MouseEvent.CLICK, _onMouseClick)

В любой другой ситуации - например, для барботажа установлено значение false, вещатель не является InteractiveObject в списке отображения или (как в вашем случае), слушатель ниже, чем вещатель в иерархии списка отображения - объект, вещающий событие, должен быть специально прослушен:

fooInstance.addEventListener(Event.BAR, _bazFunc)
as против
addEventListener(Event.BAR, _bazFunc)

В основном вам необходимо передать ссылку на родительский объект на дочерний swf, чтобы он мог присоединить к нему обработчики событий.

Один из способов - отправить событие от ребенка родительскому классу через список отображения (после того, как ребенок загрузился и полностью инициализирован). Родитель использует свойство event.target этого события для ссылки на дочерний элемент и устанавливает для него переменную parentClass. Это может быть использовано для прикрепления слушателей:

package { 


    class ChildClass 
    { 
     private var __parentClass:ParentClass; 

     // EventID to listen for in ParentClass 
     public static const INITIALISED:String = "childInitialised"; 

     // Constructor 
     function ChildClass() 
     { 
      // Do initialising stuff, then call: 
      _onInitialised(); 
     } 

     private function _onInitialised():void 
     { 
      // Dispatch event via display hierarchy 
      // ParentClass instance listens for generic events of this type 
      // e.g. in ParentClass: 
      //  addEventListener(ChildClass.INITIALISED, _onChildInitialised); 
      //  function _onChildInitialised(event:Event):void { 
      //   event.target.parentClass = this; 
      //  } 
      // @see mutator method "set parentClass" below 
      dispatchEvent(new Event(ChildClass.INITIALISED, true); 
     } 

     public function set parentClass(value:ParentClass):void 
     { 
      __parentClass = value; 

      // Listen for the events you need to respond to 
      __parentClass.addEventListener(ParentClass.FOO, _onParentFoo, false, 0, true); 
      __parentClass.addEventListener(ParentClass.BAR, _onParentBar, false, 0, true); 
     } 

     private function _onParentFoo(event:Event):void 
     { 
      ... 
     } 
    } 
} 

Диспетчерская пользовательского ChildSWFEvent - то есть вместо того, чтобы использовать класс определенный постоянный, как и выше - сделает это более гибкое решение, так как экземпляр ParentClass может прослушивать общей ChildSWFEvent .INITIALISED событие, переданное любым дочерним swf с контекстно-полезной информацией, переданной в качестве дополнительного параметра.

0

Я бы слушать каждый ребенок для

Event.ADDED_TO_STAGE 

когда он был добавлен к стадиям, то вы можете ссылаться/слушать на сцену для проведения мероприятий.

Пример

//Child 
if(stage) _init(); //Already added 
else addEventListener(Event.ADDED_TO_STAGE, _init); //waiting to be added 

private function _init(e:Event = null):void 
{ 
    stage.addEventListener(CustomEvent.CHANGED, _onStageChanged); 
{ 

Я не проверял это, но до тех пор, как вы посылаете события со сцены, он должен работать.

//stage 
dispatchEvent(new CustomEvent(CustomEvent.CHANGED)); 

, если вы правильно настроили свой собственный класс событий, вы также можете передавать информацию.

1

При загрузке дочернего swf (Main.swf) в родительском swf (указатель.швейцарские франки), сохранить ссылку в переменном переменном поле или класс

fldMain = BulkLoader.getLoader("Index").getContent("Main.swf") as DisplayObject; 
this.addChild(fldMain); 

(я использую BulkLoader загружать любой контент)

Это хорошая практика, чтобы ждать с диспетчерскими событиями, пока ребенок не будет добавил (ADDED_TO_STAGE событие)

Когда я хочу послать событие, чтобы мой ребенок, я просто говорю:

fldMain.dispatchEvent(new CustomEvent(CustomEvent.INIT_CHILD,data)); 
+0

Очень приятно, легко и просто. Благодаря! – cregox

0

Что я сделал, так это добавить слушателя родителя для изменений после того, как ребенок добавлен на сцену. Теперь, когда вы хотите, чтобы дети имели дело с обновлением, просто отправьте Event.CHANGE от родителя. Bubbling может быть истинным или ложным.

Я бы подумал, что если вы присоедините слушателя к Сцене (stage.addEventListener...), любой объект, который выбрасывает Event.CHANGE, может вызвать дочерний элемент для обработки события.

package 
{ 
    import flash.display.* 
    import flash.events.* 

     public class Child extends Sprite 
     { 

      public function Child():void 
      { 
       this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler, false, 0, true); 
      } 

      private function addedToStageHandler(pEvent:Event):void 
      { 
       trace("CHILDADDED"); 
       this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); 
       this.parent.addEventListener(Event.CHANGE, parent_changeEventHandler, false, 0, true); 
      } 

      private function parent_changeEventHandler(pEvent:Event):void 
      { 
       trace("PARENT_CHANGED"); 
      } 
     } 
} 
0

IMO, он почти никогда не подходит ребенку, чтобы знать или заботиться о его родителе. С другой стороны, родители почти всегда знают все о своих детях (поскольку они имеют прямую ссылку на них). Поэтому в этом случае я просто создаю свойство или метод для дочернего класса, который может быть установлен/вызван родителем при необходимости.

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

HTH;

Amy

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