Какая уместная форма при отправке событий в 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");
        }
    }
}
Другие вопросы по тегам