PDA

Просмотр полной версии : подписаться на событие от произвольного элемента


Minras
05.09.2008, 02:34
имеем: кастомный компонент MessageBox, который при разработке вставляем в произвольное место приложения.
компонент слушает кастомное событие MessageBroadcastEvent, которое запускается функцией
public function confirmation(target:Object, text:String):void
{
var _event:MessageBroadcastEvent = new MessageBroadcastEvent(MessageBroadcastEvent.MESSAGE, text);
target.dispatchEvent(_event);
}


требуется: определить, от имени какого элемента нужно делать dispatchEvent(), а какой элемент должен делать addEventListener(). заодно избавиться от параметра target в вызове функции.

согласно мануалу о event propagation (http://livedocs.adobe.com/flex/3/html/events_08.html#203937), событие, которое диспатчится объектом, может услышать только сам объект или его родители.

так как местоположение компонента в документе неизвестно, то из родителей известны только Application и выше.

соответственно, чтобы отловить событие, есть несколько вариантов:
1) запускать и слушать событие от имени Application.application (вариант не нравится, так как логически событие и перехват не имеют отношения к Application.application)
2) запускать и слушать событие от имени кастомного компонента MessageBox (не нравится, так как прийдётся добавлять ссылку на MessageBox в класс, генерящий событие, а это лишние связи)

wvxvw
05.09.2008, 03:00
Если в компоненте MessageBox до объявления класса есть строчка:
[Event(name="customName", type="my.package.events.CustomEvent")]
то в МХМЛе можно на него подписаться точно так же, как и на любое другое событие от стандартного компонента:
<customNamespace:MessageBox customName="handleCustomEvent(event)">

Родителю передаются только всплывающие события, так что если ваше событие не всплывающее - никто кроме явно объявленых подписчиков его не услышит.

Слушать событие нужно от того, кто его диспатчит... мне тяжело понять, зачем вы это пытаетесь поменять...

Minras
08.09.2008, 20:37
Слушать событие нужно от того, кто его диспатчит

хотелось сделать так:
есть различные элементы, при различном взаимодействии с которыми вызывается метод объекта, генерящий наше событие, например:
<mx:CheckBox click="obj.dispatch('text')" />
<mx:CheckBox buttonDown="obj.dispatch('text2')" />
т.е. эти элементы передают диспатчеру какой-то текст, тот его сохраняет и "выплёвывает" событие в окружающую среду.

наш кастомный компонент слушает среду, вылавливает событие, и что-то делает с сохраненным диспатчером текстом.

проблема в том, что событие слушается кастомным компонентом, а диспатчер ничего не знает о существовании кастомного компонента и может диспатчить событие только от имени какого-то другого объекта (сейчас это Application.application). но кастомный компонент не слышит событие от Application.application, приходится слушать событие тоже от имени Application.application :(

хотелось бы убрать листенеры и диспатчеры с Application.application на более подходящий с точки зрения логики объект, но не представляю, на какой.

я слишком путанно объясняюсь? :)

пс: спасибо за ответ

wvxvw
08.09.2008, 21:55
Ну если все компоненты должны слушать события от одного диспатчера, то к нему и нужно добавлять слушателя... Если такой диспатчер обязан быть единственным, то можно доступ к нему сделать статическим типа:
MyDispatcher.getInstance():MyDispatcher (синглтон / одиночка) только, как правило, это нехорошее решение, и диспатчер вовсе не обязан быть единственным.

Minras
09.09.2008, 01:30
Ну если все компоненты должны слушать события от одного диспатчера, то к нему и нужно добавлять слушателя
если смотреть с позиции "кто файрит ивент, тот его и слушает", то да, а с точки зрения минимизации количества зависимостей между классами - єто плохо, так как диспатчер не обязан знать, кто его будет слушать. и в данной реализации наш кастом компонент живёт отдельно, класс-диспатчер отдельно, компоненты в основном эппликейшн - отдельно.

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

(синглтон / одиночка) только, как правило, это нехорошее решение, и диспатчер вовсе не обязан быть единственным
да, класс диспатчер у меня является синглтоном, и я не вижу в этом никаких минусов, сплошной позитив :)
даже абстрагируясь от остальных функций класса-диспатчера, оперируя только описанными в этой теме, не вижу ни одного аргумента в пользу содержания нескольких классов-диспетчеров

wvxvw
09.09.2008, 04:31
>> если смотреть с позиции "кто файрит ивент, тот его и слушает", то да, а с точки зрения минимизации количества зависимостей между классами - єто плохо,

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

м... вообще-то все с точностью до наоборот... это одна из "фичь" mx фреймворка, изза которых я его не использую =) ну, вот, представьте, у вас есть фокус менеджер в приложении, в котором этот фокус просто некуда переводить... а он там все равно есть... один диспатчер на всех сделает его импорт обязательным не зависимо от реального количества слушателей (которых может не оказаться вовсе). Кроме того, этот самый диспатчер должен будет выполнять кучу очень отдаленно связаных между собой функций - результат - еще + % никому не нужного кода, ну и т.д. и т.п.