Работа с событиями

advertisement
Работа с событиями
в ActionScript 3 и Adobe Flex
Жизнь без событий
Окно
кнопкаНажата (Кнопка)
родительскоеОкно.кнопкаНажата (я)
Кнопка
изменитьМетку (Строка)
Жизнь без событий
Окно
кнопкаНажата (Кнопка)
кнопка.изменитьМетку («Нажата»)
Кнопка
изменитьМетку (Строка)
Жизнь без событий
• Кнопка и Окно знают друг о друге
• Нельзя повторно использовать Кнопку
Жизнь с событиями
Окно
кнопкаНажата (Событие)
кнопка.регистрировать (кнопкаНажата)
Кнопка
регистрировать (Функция)
изменитьМетку (Строка)
Жизнь с событиями
Окно
кнопкаНажата (Событие)
Событие нажатия и вызов обработчика
Кнопка
регистрировать (Функция)
изменитьМетку (Строка)
Жизнь с событиями
Окно
кнопкаНажата (Событие)
кнопка.изменитьМетку («Нажата»)
Кнопка
регистрировать (Функция)
изменитьМетку (Строка)
Жизнь с событиями
• Окно знает о Кнопке
• Кнопка ничего не знает об Окне
• Кнопку можно повторно использовать!
Кирпичики событий
•
•
•
•
•
•
•
Событие
Извещение (dispatch)
Поведение по умолчанию
Поток события (event flow)
Event object
Event target
Обработчик (listener)
Реализации событийной
модели
•
•
•
•
•
•
on () – на кнопках и мувиклипах
onClipEvent () – на мувиклипах
XML.onLoad – методы-обработчики
addListener () – листенеры
addEventListener () – UIEventDispatcher
DOM Level 3 !!!
Поведение по
умолчанию
• Отсутствует у большинства событий
• Не всякое поведение можно отменить
• Бывает только у событий,
генерируемых Flash Player’ом
• Можно сделать аналог для кастомных
событий
Демо
Поведение по умолчанию.
PreventDefault.mxml
Event flow
Поток события
Структура визуальных
объектов
Сцена
Application
Box1
Box2
Структура визуальных
объектов
Сцена
Сцена
Application
Application
Box1
Box2
Box1
Box1
Фазы событий
• Фаза захвата (capture)
• Целевая фаза (target)
• Фаза пузырька (bubbling)
Capture phase
(фаза захвата)
Сцена
Application
Box1
Box1
Target phase
(целевая фаза)
Сцена
Application
Box1
Box1
Bubbling phase
(фаза пузырька)
Сцена
Application
Box1
Box1
Event flow
Сцена
Фаза захвата
Application
Box1
Целевая фаза
Фаза пузырька
Box1
Event flow
• Только для Display List
– Можно сделать некоторый аналог
• События клавиатуры и мыши
(интерактив)
• Event flow = capture + bubbling
• Event object
Event object
• Наследуются от flash.events.Event
• Описывают событие
Свойства Event Object
•
•
•
•
•
•
type
cancelable
bubbles
eventPhase
target
currentTarget
type
•
•
•
•
Строка, идентифицирующая событие
Только для чтения
Устанавливается в конструкторе
Event (type:String, bubbles:Boolean =
false, cancelable:Boolean = false)
• При наследовании пользоваться super
(type)
type: best practice
package com.riapriority.events
{
import flash.events.Event;
public class TestEvent extends Event
{
public static const MY_EVENT:String = "myEvent";
public static const ANOTHER_EVENT:String = "anotherEvent";
public function TestEvent(type:String)
{
super(type);
}
}
}
cancelable
• Информация о возможности отмены
поведения по умолчанию
• Актуально только для событий Flash
Player’а (пакет flash.*)
• Можно использовать для организации
собственного поведения по умолчанию
bubbles
• Относится к event flow
• Показывает, участвует ли событие в
баблинге
• Если true, то capture + target + bubbling
• Если false, то target phase
• Может использоваться в собственных
событиях
eventPhase
• Текущая фаза потока событий
package flash.events
{
public final class EventPhase
{
public static const CAPTURING_PHASE:uint = 1;
public static const AT_TARGET:uint = 2;
public static const BUBBLING_PHASE:uint= 3;
}
}
target
• Ссылка на объект, являющийся целю
события
Сцена
Application
target
Box1
Box1
currentTarget
• Ссылка на текущий объект в event flow
Сцена
currentTarget
Application
target
Box1
Box1
target и currentTarget
• bubbles=false => target=currentTarget
• target=currentTarget => eventPhase=2
• eventPhase=2 => target=currentTarge
Демо
Свойства Event object
EventTestsClick.mxml
EventTestsClickCapture.mxml
Методы Event Object
•
•
•
•
•
preventDefault ()
isDefaultPrevented ()
stopPropogation ()
stopImmediatePropogation ()
clone ()
preventDefault () и
isDefaultPrevented ()
• preventDefault () отменяет действие по
умолчанию
• isDefaultPrevented () проверяет,
отменено ли действие
• cancelable=false =>
isDefaultPrevented ()=false
stopPropogation ()
• Отменяет вызов обработчиков в event
flow
Сцена
Listener 1
Application
Listener 2
Box1
stopPropogation ()
stopImmediatePropogation ()
• Отменяет вызов обработчиков в event
flow
Сцена
Listener 1
Application
Listener 2
Box1
stopImmediatePropogation ()
clone()
• Необходимо реализовывать при
создании собственных событий
• Используется во внутренних
механизмах диспетчеризации событий
• dispatchEvent(event)
Подписка и обработка
IEventDispatcher
package flash.events
{
public interface IEventDispatcher
{
function addEventListener(eventName:String, listener:Object,
useCapture:Boolean=false, priority:Integer=0,
useWeakReference:Boolean=false):Boolean;
function removeEventListener(eventName:String, listener:Object,
useCapture:Boolean=false):Boolean;
function dispatchEvent(eventObject:Event):Boolean;
function hasEventListener(eventName:String):Boolean;
function willTrigger(eventName:String):Boolean;
}
}
addEventListener
•
•
•
•
•
eventName: MouseEvent.CLICK, "click“
listener: ссылка на метод-обработчик
useCapture: участие в capture phase
priority: чем больше, тем раньше
useWeakReference: сборка мусора
addEventListener
• Простейший случай
addEventListener(MouseEvent.CLICK,
clickHandler);
– Подписка на target и bubbling phase
• addEventListener(MouseEvent.CLICK,
clickHandler, true);
– Подписка только на capture phase
• Оба вызова – подписка на все фазы
addEventListener
• priority может быть отрицательным
• Одинаковый приоритет – в порядке
добавления
• useWeakReference позволяет не
вызывать removeEventListener
removeEventListener
• Для удаления обработчиков всех фаз
вызывайте дважды (useCapture)!
• Удаляйте обработчики
несуществующих объектов!
• Или используйте weak reference
Диспетчеризация
событий
• dispatchEvent (event)
• target для event устанавливается
автоматически (вызывающий объект)!
• Например:
dispatchEvent (new MyEvent
(MyEvent.EVENT));
• Чаще всего при создании собственных
компонент
hasEventListener()
и willTrigger()
• hasEventListener(eventName:String):
Boolean – подписался ли кто-то на
событие?
• willTrigger(eventName:String):Boolean –
то же самое с учетом event flow
Обработчики событий
• function someHandler
(event:Event):void
• Обязательно указать один параметр!
• Параметр – наследник
flash.events.Event
• someHandler (event:MouseEvent =
null):void
• someHandler (event:Event,
second:Boolean = false):void
Диспетчеры событий
•
•
Наследование:
class SomeClass extends EventDispatcher
Композиция:
package
{
class SomeClass implements IEventDispatcher
{
private var dispatcher:EventDispatcher;
public function SomeClass ()
{
// this в конструкторе для автоматического указания target
dispatcher = new EventDispatcher (this);
}
…
public function dispatchEvent(eventObject:Event):Boolean
{
return dispatcher.dispatchEvent (eventObject);
}
}
}
События в MXML
<mx:Button
click=“trace(‘Test!’)“
label=“Test” />
• Используется простая подписка
addEventListener(MouseEvent.CLICK, clickHandler);
• target и bubbling phase
• Можно использовать ключевое слово event:
<mx:Button
click=“trace(event.eventPhase)“
label=“Test” />
• Нет легального способа отписки!!!
События в MXML
<mx:Script>
<![CDATA[
private function onClick ():void {trace(“Test!”);}
]]>
</mx:Script>
<mx:Button click=“onClick ()“ label=“Test” />
Либо
<mx:Script>
<![CDATA[
private function onClick (event:MouseEvent):void
{trace(event.eventPhase);}
]]>
</mx:Script>
<mx:Button click=“onClick (event)“ label=“Test” />
Метатэги
• Используется в mxml (для компилятора и
автокомплита)
• name – текст, а не константа!
• package {
[Event(name="myEvent",type="com.riapriority.events.
TestEvent")]
class SomeClass extends EventDispatcher {
…
}
• Или:
<mx:Metadata>
[Event(name="myEvent",type="com.riapriority.events.
TestEvent")]
</mx:Metadata>
Кастомные события
package com.riapriority.events {
import flash.events.Event;
public class TestEvent extends Event {
public static const MY_EVENT:String = "myEvent";
public static const ANOTHER_EVENT:String = "anotherEvent";
public function TestEvent(type:String, bubbles:Boolean = false,
cancelable:Boolean = false) {
super(type, bubbles, cancelable);
}
override public function clone():Event {
return new TestEvent (type, bubbles, cancelable);
}
}
}
Советы
• Отписываться от ненужных событий
• Трансформировать низкоуровневые
события в события бизнес-логики
– Для окна логина нажатие на кнопку Логин:
• MouseEvent.CLICK – неправильно
• LoginEvent.LOGIN – правильно!
Демо
Кастомные события
CustomEvents.mxml
Q&A
Константин Ковалев
http://riapriority.com/
constantiner@riapriority.com
Download