Какая уместная форма при отправке событий в AS3?
Мне было интересно, что подходящая форма была при создании пользовательских событий? Следует ли создать класс CustomEvent, а затем создать временный диспетчер в функции и отправить CustomEvent. или лучше попытаться создать класс CustomEventDispatcher и создать класс CustomEvent как внутренний класс этого класса, например:
package
{
public class CustomEventDispatcher extends EventDispatcher
{
public function CustomEventDispatcher()
{
super(new CustomEvent());
}
}
}
class CustomEvent
{
public function CustomEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable)
}
}
3 ответа
Есть два основных вопроса, на которые нужно ответить при разработке механики событий.
1) Как создать экземпляр диспетчера для моих событий?
Общие параметры: расширение EventDispatcher или агрегатный экземпляр диспетчера.
Наиболее распространенная и распространенная практика (и официальные документы также утверждают, что) расширяет класс EventDispatcher, тем самым предоставляя вашим классам возможности диспетчеризации событий.
Плюсы: прост в реализации - просто расширяет EventDispatcher, и все готово.
Минусы: вы не можете расширить что-то еще. По-видимому, именно поэтому многие нативные классы являются внуками EventDispatcher. Я думаю, просто чтобы избавить нас от неприятностей.
Второй общий подход - агрегирование экземпляра диспетчера.
package
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
public class ClassA implements IEventDispatcher
{
private var dispatcher:EventDispatcher;
public function ClassA()
{
initialize();
}
private function initialize():void
{
dispatcher = new EventDispatcher(this);
}
public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
{
dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
}
public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void
{
dispatcher.removeEventListener(type, listener, useCapture);
}
public function dispatchEvent(event:Event):Boolean
{
return dispatcher.dispatchEvent(event);
}
public function hasEventListener(type:String):Boolean
{
return dispatcher.hasEventListener(type);
}
public function willTrigger(type:String):Boolean
{
return dispatcher.willTrigger(type);
}
}
}
Примечание: мы передаем ссылку на агрегирующий класс в конструктор диспетчера. Это сделано для того, чтобы event.target ссылался на ваш экземпляр класса, а не на сам экземпляр диспетчера.
Плюсы: вы можете распространять все что угодно. Вы можете сделать некоторые трюки с диспетчерскими хуками, например, поддерживать список слушателей или что-то подобное.
Минусы: не так просто, как при первом подходе.
2) Как передать пользовательские данные с моими событиями?
Общие параметры: передавать данные в экземпляре события или использовать только ссылку на event.target в обработчике событий для доступа к некоторым данным из источника.
Если вы решите получить доступ ко всем необходимым данным через event.target - без дополнительной работы, просто приведите эту ссылку в обработчике событий к соответствующему классу.
Если вы хотите передать некоторые данные вместе с событием, вы создаете подкласс Event, и этот класс должен быть публично видимым для кода, который обрабатывает события, как указано в ответе выше. AS3 все о строгой и строгой печати, так почему бы вам не сопротивляться этому?
Переопределение метода clone() в подклассе Event необходимо только в том случае, если вы собираетесь повторно отправлять обработанные события. Официальные документы говорят, что вы должны делать это каждый раз, когда создаете собственный класс событий, просто чтобы быть в безопасности.
В одностороннем порядке лучше делать мероприятия общедоступными. Таким образом, вы можете набирать своих слушателей (хорошо для хинтинга и отладки кода), и у Event будут открытые типы статических констант (к которым вы также можете обратиться).
Не забудьте переопределить клон также хорошая идея переопределить toString для отладки.
Вот пример одного из моих пользовательских событий:
package com.mattie.events
{
//Imports
import flash.events.Event;
//Class
public class SearchFieldEvent extends Event
{
//Constants
public static const SEARCH_COMPLETE:String = "search complete";
//Variables
public var totalResults:uint;
public var duration:uint;
public var searchText:String;
//Constructor
public function SearchFieldEvent(type:String, totalResults:uint = 0, duration:uint = 0, searchText:String = "")
{
super(type);
this.totalResults = totalResults;
this.duration = duration;
this.searchText = searchText;
}
//Override clone
public override function clone():Event
{
return new SearchFieldEvent(type, totalResults, duration, searchText);
}
//Override toString
public override function toString():String
{
return formatToString("SearchFieldEvent", "type", "totalResults", "duration", "searchText");
}
}
}