Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > Flex

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 16.12.2011, 02:48
Dimitry_II вне форума Посмотреть профиль Отправить личное сообщение для Dimitry_II Найти все сообщения от Dimitry_II
  № 1  
Ответить с цитированием
Dimitry_II

Регистрация: Jan 2010
Сообщений: 211
По умолчанию Передача параметров в хандлер и отписывание от события

Допустим, есть такой код:
Код AS3:
private function someFunction(param:int):void {
    ...
    var animate:Animate = new Animate();
    ...
    animate.addEventListener(EffectEvent.EFFECT_END, someHandler);
    ...
}
protected function someHandler(event:EffectEvent):void {
    (event.target as Animate).removeEventListener(EffectEvent.EFFECT_END, someHandler);
    //some action
}
Как бы вопросов не возникает с назначением хандлера и отписки.
Если необходимо передать параметр в хандлер, то (на мой взгляд) наилучшим решение является следующее (можно использовать вариацию, переписав конструктор):
Код AS3:
private function addArguments(method:Function, additionalArguments:Array):Function { 
    return function(event:Event):void {method.apply(null, [event].concat(additionalArguments));} 
}
...
private function someFunction(param:int):void {
    ...
    var animate:Animate = new Animate();
    ...
    animate.addEventListener(EffectEvent.EFFECT_END, addArguments(someHandler, [param]));
    ...
}
protected function someHandler(event:EffectEvent, param:int):void {
    (event.target as Animate).removeEventListener(EffectEvent.EFFECT_END, someHandler); //вот тут
    //some action
}
Так вот в чем вопрос: для того, чтобы убрать хандлер события (отписаться от события), в данном случае правильно указывать
Код AS3:
removeEventListener(EffectEvent.EFFECT_END, someHandler)
или
Код AS3:
removeEventListener(EffectEvent.EFFECT_END, addArguments(someHandler, [param]))
?
Спасибо.

Старый 16.12.2011, 03:36
crazyone вне форума Посмотреть профиль Отправить личное сообщение для crazyone Найти все сообщения от crazyone
  № 2  
Ответить с цитированием
crazyone
 
Аватар для crazyone

блогер
Регистрация: Nov 2007
Адрес: Киев
Сообщений: 557
Записей в блоге: 2
Ни то, ни другое.
Прежде всего - такой способ передачи параметров в обработчик является дурным тоном. Обработчик должен обрабатывать только событие, а не событие и параметр. У события, как правило, достаточно свойств, чтобы обработчик смог выполнить необходимое действие.

Если же мои слова звучат неубедительно и вам хочется использовать этот способ, то для отписки от события вам прийдется:
а) сохранить ссылку на анонимную функцию, возвращаемую вашим addArguments;
б) использовать arguments.callee из тела вашей анонимной функции;
в) передавать arguments.callee из тела вашей анонимной ф-и в ваш обработчик.
а:
Код AS3:
var handler:Function;
handler=addArguments(someHandler,[param]);
animate.addEventListener(EffectEvent.EFFECT_END,handler);
...
removeEventListener(EffectEvent.EFFECT_END,handler);
б:
Код AS3:
private function addArguments(method:Function, additionalArguments:Array):Function { 
    return function(event:Event):void {
        method.apply(null, [event].concat(additionalArguments));
        event.currentTarget.removeEventListener(event.type,arguments.callee);
    } 
}
в:
Код AS3:
private function addArguments(method:Function, additionalArguments:Array):Function { 
    return function(event:Event):void {
        method.apply(null, [event].concat(additionalArguments),arguments.callee);
    } 
}
protected function someHandler(event:EffectEvent, param:int,handler:Function):void {
    event.currentTarget.removeEventListener(EffectEvent.EFFECT_END, handler); //вот тут
    //some action
}

PS вызывать removeEventListener нужно именно у event.currentTarget, потому что в target может быть что угодно, а в currentTarget - именно объект, который диспатчит событие.

Старый 16.12.2011, 15:34
Dimitry_II вне форума Посмотреть профиль Отправить личное сообщение для Dimitry_II Найти все сообщения от Dimitry_II
  № 3  
Ответить с цитированием
Dimitry_II

Регистрация: Jan 2010
Сообщений: 211
Огромное спасибо ... нет слов.

Правда, возникают вопросы ...
По поводу дурного тона спорить не буду, думаю, что даже согласен. Просто не хочется создавать кастомное событие, которое бы содержало хранимые параметры (даже не знаю почему), а штатные средства так делать не могут. Поэтому такой вариант мне кажется вполне удобоваримым.

Второй вариант действительно облегчает жизнь - не нужны лишние вызовы и удаление будет под контролем.

Правда, возникает вопрос к третьему варианту: хандлер - статическая функция (в смысле, что не создается динамически, а не имеет ключевое слово атрибута static), и arguments.callee будет равно someHandler, то есть параметр handler у функции будет указывать на саму функцию. То есть несколько абсурдна запись - это раз, а второе - если следовать логике, то мой первый вариант правильный.

P.S. 50 на 50, что ошибаюсь и все легко проверяется трейсами в коде, но как-то сейчас рука не поднимается этим заниматься

Старый 16.12.2011, 15:54
crazyone вне форума Посмотреть профиль Отправить личное сообщение для crazyone Найти все сообщения от crazyone
  № 4  
Ответить с цитированием
crazyone
 
Аватар для crazyone

блогер
Регистрация: Nov 2007
Адрес: Киев
Сообщений: 557
Записей в блоге: 2
В третьем варианте arguments.callee предается из анонимной функции и указывает именно на нее, а не на someHandler.

Добавлено через 3 минуты
Он, в принципе, аналогичен второму варианту, только отписка происходит не в анонимной функции, а в вашем обработчике. Этот вариант позволит вам контролировать отписку от события, т.е. - отписаться не сразу после события, а по какому-то условию.

Старый 16.12.2011, 16:03
Dimitry_II вне форума Посмотреть профиль Отправить личное сообщение для Dimitry_II Найти все сообщения от Dimitry_II
  № 5  
Ответить с цитированием
Dimitry_II

Регистрация: Jan 2010
Сообщений: 211
Проверка очень проста. Использовал второй вариант и:
Код AS3:
protected function someHandler(event:EffectEvent, i:int):void {
    Alert.show("" + (event.currentTarget as Animate).hasEventListener(EffectEvent.EFFECT_END));
 
    (event.currentTarget as Animate).removeEventListener(EffectEvent.EFFECT_END, someHandler);
    Alert.show("" + (event.currentTarget as Animate).hasEventListener(EffectEvent.EFFECT_END));
 
    (event.currentTarget as Animate).removeEventListener(EffectEvent.EFFECT_END, addArguments(someHandler, [i]));
    Alert.show("" + (event.currentTarget as Animate).hasEventListener(EffectEvent.EFFECT_END));
}
Все 3 алерта выдают true. То есть событие по-прежнему висит на объекте.

Добавлено через 8 минут
... Или это GC еще не добрался до них (него) и событие все еще висит ... пока?

Старый 16.12.2011, 16:13
crazyone вне форума Посмотреть профиль Отправить личное сообщение для crazyone Найти все сообщения от crazyone
  № 6  
Ответить с цитированием
crazyone
 
Аватар для crazyone

блогер
Регистрация: Nov 2007
Адрес: Киев
Сообщений: 557
Записей в блоге: 2
Ну так во втором варианте отписка от события происходит после вызова метода, в котором вы делаете проверку.
Можете поменять их местами.

Старый 16.12.2011, 16:19
Dimitry_II вне форума Посмотреть профиль Отправить личное сообщение для Dimitry_II Найти все сообщения от Dimitry_II
  № 7  
Ответить с цитированием
Dimitry_II

Регистрация: Jan 2010
Сообщений: 211
Точно! Обидно на таких вещах прокалываться. Еще раз огромное спасибо!

Зато для себя убедился, что оба моих варианта однозначно нерабочие.

Создать новую тему Ответ Часовой пояс GMT +4, время: 18:36.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 18:36.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.