Показать сообщение отдельно
Старый 16.10.2013, 05:22
elder_Nosferatu вне форума Посмотреть профиль Отправить личное сообщение для elder_Nosferatu Найти все сообщения от elder_Nosferatu
  № 5  
Ответить с цитированием
elder_Nosferatu
 
Аватар для elder_Nosferatu

Регистрация: Nov 2010
Адрес: 48° 55'N 24° 42'E GMT +2:00
Сообщений: 399
Записей в блоге: 1
Во первых ожидается не константа, а строка - будет она сохранена в константе, переменной или просто записана, как литерал - без разници. Так что если Вас напрягает писать Event.COMPLETE, то можете просто указать значение этой константы - "complete". Но эти константы не зря придумали. Помимо их прямого назначения, как констант, они еще несут в себе функцию подсказки. Если Ваш IDE поддержывает автозаполнение, тогда он Вам и подскажет точное название константы по первых буквах. Но если вместо константы вы будете набирать литерал "complete", тогда у Вас больше шансов сделать оЧЕПятку.

Еще в пользу констант. Обратите внимание на константы "родных" событий. Все они сохранены, как статические члены класса самого события, а значит используя это событие (читай импортируя класс события в приложение) Вы вместе с ним тянете и константы его типов. Так что не использовать эти константы просто глупо.

Также замечу, что заявленые константы типов никак не ограничивают набор возможных событий. Они носят только информативно-вспомогательный характер. Так что можно спокойно разослать событие класса Event с типом "oops_I_did_it_again". Беда только, что стороннему человеку будет сложно догадаться без подсказки, что такого события можно ожидать.

На счет личных событий. Если экземпляры Вашего класа хотят рассылать события, то не стоит спешить создавать для этого класса собственный класc событий. Можна использовать одно из стандартных событий. А если оно будет не достаточно информативным, тогда стоит создать свой класс события с необходимыми свойствами для хранения той инфы, которая должна передаваться с событем. Например универсальное событие Event. Его использует множество классов - события и сцены и редактирования текста и конец звука и смены кадров и т.д. и т.п. Но каким бы полезным не был класс Event, его информативности не хватает для клавиатуры. Вот для нее уже создали свое событие, которое предоставляет больше информации. Короче суть в том, что перед тем, как ваять свой класс события, следует думать не о том, кто его собирается рассылать, а о самом событии (не о классе, а о... явлении, что ли?). Хорошим примером будет MouseEvent. Его рассылает целая свора ИнтерактивныхОбъектов, но класс назвали не SpriteEvent, не ButtonEvent, не TextFieldEvent, и даже не InteractiveEvent, а MouseEvent. Интересно то, что класс Mouse (которому, по незнанию, можно было бы приписывать события класса MouseEvent) не наследует EventDispatcher, а значит его экземпляры и не могут рассылать события. Он вообще не имеет ничего полезного, кроме статических членов (его екземпляры ничем не будут отличаться от Object).

Упомяну еще две "хитрости". Полезного в них мало, но они помогут точнее понимать происходящее. Это как с Истиной. Человек, говоря Правду, расказывает Истину, но ставит акценты на то, что считает важным, тем самым уменьшает значение остального, превращая его в "тонкости" и "нюансы". Этим "грешат" все авторы, но...
Итак:
#1: Регистрируя обработчик события, EventDispatcher принимает ссылку на функцию. Никто не запрещает для нескольких событий использовать один обработчик. Для чего?
Вариант 1: когда я пишу класс кнопки, мне нужно запрограмировать ее поведение. Не знаю, как у кого а мои кнопки, будучи нажатымы, возвращаются в исходное положение, когда я их отпускаю и когда убираю с них курсор (даже если LMB все еще зажата). А значит я использую один обработчик для событий "mouseUp" и "rollOut".
Вариант 2: чтобы не плодить кучу методов-обработчиков я делаю все в одном единственном. Метод сомнительный, но возможность такая есть.
Код AS3:
var btn:MyButton = MyButton();
btn.addEventListener(MouseEvent.CLICK, mouseHandler);
btn.addEventListener(MouseEvent.MOUSE_UP, mouseHandler);
btn.addEventListener(MouseEvent.MOUSE_DOWN, mouseHandler);
btn.addEventListener(MouseEvent.MOUSE_MOVE, mouseHandler);
btn.addEventListener(MouseEvent.MOUSE_OVER, mouseHandler);
btn.addEventListener(MouseEvent.MOUSE_OUT, mouseHandler);
function mouseHandler(event:MouseEvent):void {
	switch (event.type) {
		case MouseEvent.CLICK		: /* do click */ break;
		case MouseEvent.MOUSE_UP	: /* do up */	 break;
		case MouseEvent.MOUSE_DOWN	: /* do down */	 break;
		case MouseEvent.MOUSE_MOVE	: /* do move */	 break;
		case MouseEvent.MOUSE_OVER	: /* do over */	 break;
		case MouseEvent.MOUSE_OUT	: /* do out */	 break;
	}
}
#2:Функция-обработчик ожыдает не столько экземпляр определенного класса, сколько какой-нибудь объект. Следовательно она справится с любым из наследников класса Object. Например, если Вас не интересуют детали события класса MouseEvent(ну там delta, altKey, ctrlKey, shiftKey, localX, stageY...), а всего лишь факт самого события, то в обработчике события можна запрашивать не MouseEvent, а его предка (Event или Object). Спросите "Зачем?" Я без понятия. Спросите "Сработает ли?" 100-пудово! Сам проверял.
Код AS3:
var btn:MyButton = MyButton();
btn.addEventListener(MouseEvent.CLICK, clickHandler);
btn.addEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
function clickHandler(event:Object):void {
	trace("Oops...");
}
function moveHandler(event:Object):void {
	trace("LOCAL POS:", event.localX + ", " + event.localY);
}
Все, пошел спать!