четверг, февраля 28, 2008

Про EventDispatcher. AS2

Повторение - мать учения.

Как использовать EventDispatcher:

Класс объекта, посылающего события:
import mx.events.EventDispatcher;

/**
* Класс отправителя события
*/
class Sender {

/**
* Идентификатор события
*/
static public var EVENT_TYPE:String="event_type" ;

/**
* Добавить слушателя
*/
public var addEventListener:Function;

/**
* Удалить слушателя
*/
public var removeEventListener:Function;

/**
* Генерировать событие
*/
private var dispatchEvent:Function;

/**
* Конструктор
*/
function Sender() {
EventDispatcher.initialize(this);
}

/**
* Послать событие
*/
public function dispatch() {
this.dispatchEvent({type:EVENT_TYPE});
}
}


Класс объекта, принимающего события:
import mx.utils.Delegate;

/**
* Класс обработчика события
*/
class Receiver {

/**
* Отправитель события
*/
private var __sender:Sender;

/**
* Реестр событий
*/
private var __handlers:Array;

/**
* Конструктор
*/
function Receiver() {
this.__sender=new Sender();
this.__handlers=new Array();
this.addEventListener(Sender.EVENT_TYPE,this.__sender,this,this.onEventType1);
this.addEventListener(Sender.EVENT_TYPE,this.__sender,this,this.onEventType2);
}

/**
* Обработчик события
*/
private function onEventType1(event:Object):Void {
trace("onEventType handler1"+event.type);
}

/**
* Другой обработчик события
*/
private function onEventType2(event:Object):Void {
trace("onEventType handler2"+event.type);
}

/**
* Метод тестирования обработки событий
*/
public function testDispatch() {
trace("Testing ...");
this.__sender.dispatch();
this.removeEventListener(Sender.EVENT_TYPE,this.__sender,this,this.onEventType1);
trace("Handler 1 removed ...");
this.__sender.dispatch();
this.removeEventListener(Sender.EVENT_TYPE,this.__sender,this,this.onEventType2);
trace("Handler 2 removed ...");
this.__sender.dispatch();
trace("Finish ...");
}

/*
*
*
* Методы управления обработчиками событий.
* Это пример. Управление лучше поручить специальному классу
*
*
*/

/**
* Подписаться на прослушивание события
*
* @param event Событие
* @param sender Объект-отправитель
* @param receiver Объект-получатель
* @param handler Метод-обработчик
*/
public function addEventListener(event:String,sender:Object,receiver:Object,handler:Function) {
var delegated_handler:Function=Delegate.create(receiver,handler);
this.__handlers.push({event:event,sender:sender,receiver:receiver,handler:handler,delegated_handler:delegated_handler});
sender.addEventListener(event,delegated_handler);
}

/**
* Отписаться от прослушивания события
*
* @param event Событие
* @param sender Объект-отправитель
* @param receiver Объект-получатель
* @param handler Метод-обработчик
*/
public function removeEventListener(event:String,sender:Object,receiver:Object,handler:Function) {
var i:Number=0;
while (i<this.__handlers.length) {
if ((this.__handlers[i].event==event)&&
(this.__handlers[i].sender==sender)&&
(this.__handlers[i].receiver==receiver)&&
(this.__handlers[i].handler==handler)) {
sender.removeEventListener(event,this.__handlers[i].delegated_handler);
this.__handlers.splice(i,1);
} else
i++;
}
}

}


ВАЖНО: Если объект Sender является MovieClip-ом, то в приведенном выше коде событие не отрабатывается. Для того, чтобы событие сработало, необходимо подписываться на него(вызывать addEventListener) не из конструктора! а из обработчика onLoad().

* * *

ОБНОВЛЕНИЕ: Добавление обработчика с использованием Delegate усложняет его удаление всвязи с тем, что при делегировании возвращается новая функция обработчика (см. комментарии). Для отписывания можно просто запомнить новый обработчик в переменную и потом ее использовать для отписывания:
sender.addEventListener(EVENT_TYPE,this.__event_handler=Delegate.create(this,this.onEventType1));
sender.removeEventListener(EVENT_TYPE,this.__event_handler);

В коде приведен универсальный метод подписывания на прослушивание и отписывания от событий.

Да, чуть не забыл. Для тестирования в таймлайне нужно написать:
this.reciever=new Receiver();
this.reciever.testDispatch();

2 комментария:

alexander nemtsov комментирует...

this.__sender.addEventListener(Sender.EVENT_TYPE,Delegate.create(this,this.onEventType));

ога... а теперь яви чудо изобретательности и отпишись от этого события :)

Racer комментирует...

Супер, спасибо за наводку.
Обновляю выше приведенный код.