Может ли всплывающее окно Actionscript 3 работать для пользовательских событий и иерархии объектов? - PullRequest
3 голосов
/ 14 июня 2011

Я искал в Интернете и не нашел подсказки, как это сделать, есть идеи? Я не хочу, чтобы flex только flash (мои объекты не являются визуальными компонентами).

Ответы [ 3 ]

3 голосов
/ 15 июня 2011

Пузырьки событий действительно имеют смысл только в контексте дерева отображения, потому что уже установлена ​​четкая иерархия.Если вы хотите передавать сообщения между большим количеством неэкранных объектов, лучше использовать модель концентратора событий.IE - маршрутизация событий, имеющих важное значение для всего приложения, через статический диспетчер событий:

package {
    import flash.events.EventDispatcher;

    public class EventHub {
        public static const dispatcher : EventDispatcher = new EventDispatcher();
    }
}

Затем все объекты (как отображаемые, так и не отображаемые) в вашем приложении, которые нуждаются в уведомлении, могут работать через EventHub.dispatcher:

EventHub.dispatcher.addEventListener(MyCustomEvent.TYPE, myHandlerFunction);

EventHub.dispatcher.dispatchEvent(new MyCustomEvent(MyCustomEvent.TYPE, ...));
3 голосов
/ 14 июня 2011

Пузырьки событий действительно работают только в иерархии DisplayObject, а для пользовательских событий - только ограниченным образом.

Думайте об этом так:

У экранного объекта есть родительский объект (за исключением рабочей области). Если ваш ребенок отправляет событие, имеет смысл, что это может относиться ко всему, что его содержит. Если у меня есть компонент со специальной кнопкой, которая отправляет событие «foo», я буду слушать компонент, даже если кнопка отправила событие.

С другой стороны, общие IEventDispatcher не имеют родительских отношений. Если у меня есть пользовательский объект данных, а другой объект, который является свойством этого объекта, отправляет событие, то нет смысла заставлять контейнер отправлять событие (если это не указано специально). Черт, содержащийся объект может даже не знать, что содержащийся в нем объект является диспетчером! Кроме того, если контейнер отправляется каждый раз, когда отправляется частное свойство, это в очень коротком порядке приведет к рекурсивной диспетчеризации событий и переполнению страшного стека.

Но почему я сказал, что оно ограничено?

MouseEvents пузырь. Это понятно. Но пользовательские события часто не всплывают так же, как MouseEvents. Когда MouseEvent всплывает, у него есть две фазы: фаза захвата и фаза не захвата (не знаю, как это называется). Фаза захвата начинается в root и проходит в фактическую диспетчеризацию DisplayObject, тогда как другая фаза начинается в DisplayObject, а затем проходит в root.

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

1 голос
/ 15 июня 2011

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

Также обратите внимание, что пользовательские классы событий нуждаются в методе клонирования, если отправленное событие отправляется повторно.
Например, если функция обратного вызова из пользовательского события повторно отправляет событие, метод clone сделает копию события для нового диспетчера.


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

// ActionScript file
package events{
  import flash.events.Event;    
  public class DynamicEvent extends Event{
  public var data:Object;
  private var _type:String;
  private var _bubbles:Boolean; 
  private var _cancelable:Boolean;
    public function DynamicEvent( oData:Object, sType:String, bBubbles:Boolean = false,  bCancelable:Boolean = false):void{
      super(sType, bBubbles, bCancelable);
      this.data = oData;
      this._type = sType;
      this._bubbles = bBubbles;
      this._cancelable = bCancelable;
    }
    public override function clone():Event{
      return new DynamicEvent(this.data, this._type, this._bubbles, this._cancelable );
    }
    public override function get type():String{
      return this._type;
    }
    public function set type( sType:String ):void{
      this._type = sType;
    }
    public override function get bubbles():Boolean{
      return this._bubbles;
    }
    public function set bubbles( bBubbles:Boolean ):void{
      this._bubbles = bBubbles;
    }
    public override  function get cancelable():Boolean{
      return this._cancelable;
    }
    public function set cancelable( bCancelable:Boolean ):void{
      this._cancelable = bCancelable;
    }
  }
}

[EDIT]

//usage to dispatch
var e:DynamicEvent = new DynamicEvent( {anyAttributeYouWantToCallIt:"someDataHere"}, "YourEventNameHere" );
this.dispatchEvent(e);

// usage to listen
ObjectDispatchingCustomEvent.addEventListener( 'YourEventNameHere, callBackFunc' )

//call back function
public function callBackFunc( e:DynamicEvent ):void{
   trace( e.data.anyAttributeYouWantToCallIt ) // will show someDataHere
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...