Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   команда наверх из глубокого вложения (http://www.flasher.ru/forum/showthread.php?t=141740)

Zebestov 03.07.2010 17:50

команда наверх из глубокого вложения
 
есть у меня примерно такая структура:

windowContainer -> window -> component -> someItem -> someButton

windowContainer — это DisplayObject, в котором есть метод newWindow(window:IWindow), который организует открытие нового окна и "зашторивание" открытых ранее окон. так же есть другие методы, неважно.
window — собственно окно, с методами close(), get/set enabled и т.д.
component — любой компонент. в данном случае это будут превьюшки.
someItem — объект-превьюшка. содержит картинку и пару кнопок.
someButton — кнопочка (одна из этой пары), по нажатию на которую нужно открыть новое окно в windowContainer

Ну вот собственно по неопытности парюсь, как это лучше всего обставить.
Пока варианты такие:

1. SomeButton implements IWindowOpener и содержит public function get window():IWindow. по нажатию диспатчим наверх событие-запрос, его ловит WindowContainer и делает this.newWindow((e.target as IWindowOpener).window);

2. передавать ссылку на windowContainer каждому ребенку

3. синглтон. тем более, что windowContainer в любой момент времени должен быть в единственном экземпляре.

что посоветуете, бывалые?

i.o. 03.07.2010 18:28

может быть проще подписаться на событие CLICK у кнопочки, а потом вручную вызвать windowContainer.newWindow(...). Или у вас вся структура живет своей жизнью, что выгоднее все через события делать?

expl 03.07.2010 18:29

Цитата:

1. SomeButton implements IWindowOpener и содержит public function get window():IWindow. по нажатию диспатчим наверх событие-запрос, его ловит WindowContainer и делает this.newWindow((e.target as IWindowOpener).window);
Зачем зашивать возможность окрытия окна в интерфейсе, что с этой кнопкой надо будет сделать через интерфейс IWindowOpener?

Напротив, она сама открывает окно,
что мешает просто подписаться на клик и кинуть по этому клику событие, которое поймает какой-ниь контроллер и откроет нужное окно

Да и вообще в большинстве случаев можно напрямую в обработчике клика написать windowContainer.newWindow(<наше нужное окно>)

Как сделано у нас(НЕ значит что удачно):
- Есть PopUp-манаджер, который вначале инициализируется слоем, на котором будут располагаться все окна
- Этому менеджеру вообще все равно IWindow его просят показать или DisplayObject - он просто добавляет его на слой и подкладывает подложку(если выставлен параметр "modal") - чтобы на ранее открытые окна или в игру клики не проходили
т.е. у него 2 метода addPopUp(popUp: DisplayObject, modal:Boolean) и removePopUp(popUp: DisplayObject)
- Дальше делаем окно с методом open() - в котором оно само себя добавляет в менеджер
- Нужно добавить не окно, а менюшку? - пожалуйста - интерфейс не ограничен.

Zebestov 03.07.2010 18:42

i.o.
ну просто какое окно открывать знает именно кнопка

expl
у меня все окна modal. менеджер (windowContainer) просто открывает окна и организует модальность. но ему надо подать это окно — вот и спрашиваю, как?

обоим:
ну вот я и думаю подписать windowContainer на CLICK по себе (будем ловить все что всплывает), и если e.target is IWindowOpener, то this.newWindow((e.target as IWindowOpener).window) — это и есть вариант 1 =) в данном случае интерфейс я использую для опознания что ли.

expl 03.07.2010 19:00

Цитата:

но ему надо подать это окно — вот и спрашиваю, как?
у нас менеджер - синглтон - напрямую ему окно и передаем
(Опять же, не считаю наше решение идеальным)

Цитата:

this.newWindow((e.target as IWindowOpener).window) — это и есть вариант 1 =) в данном случае интерфейс я использую для опознания что ли.
ИМХО лучше сделать событие OpenWindow и сделать у него поле window,
потому что седня кнопка открывает окно, завтра - выполяет другое действие.

Или другой вариант - была текстовая кнопка - стала кнопка-иконка
И что - давай делать ее наследника с интерфейсом IWindowOpener? как-то не комильфо.

Zebestov 03.07.2010 19:21

другими словами: вариант 3 нравится больше?

expl 03.07.2010 20:54

Ну да 3-й.
2-й тоже адекватен, но чтобы его применить нужны какие-то дополнительные причины:
- одни окна должны появляться поверх всего приложения, а другие поверх элементов внутри какой-нть скроллируемой области, т.е. возможно несколько windowContainer'ов;
- нужно протестировать элементы в отдельности от windowContainera;
- не знаю что ещё;
Если причин нет - то он только повысит сложность

Zebestov 03.07.2010 22:38

ясно. в принципе к нему склонялся больше всего.
спасибо за советы!

i.o. 03.07.2010 23:13

Если я правильно понял, то у компонента есть свойство window. Можно просто добавить свойство windowContainer в window. Следовательно, станет возможным компонентом обратится к windowContainer через window.windowContainer, т.е мы сможем достучаться до windowContainer без синглтона. Так лучше с позиции ООП.

Скрипун 04.07.2010 00:44

с позиции ООП сразу на ум пришло словосочетание "pureMVC" на слово команда )
не знаю почему, но таких задач что-то не возникало, как у автора топика

Zebestov 04.07.2010 02:10

Цитата:

Сообщение от i.o. (Сообщение 919719)
Если я правильно понял, то у компонента есть свойство window. Можно просто добавить свойство windowContainer в window.

у компонента сейчас нет свойства window

Цитата:

Сообщение от Скрипун (Сообщение 919726)
не знаю почему, но таких задач что-то не возникало, как у автора топика

хм. тоже не знаю почему )

mikhailk 04.07.2010 21:45

Не знаю, я у себя аналогичные задачи решаю через центральный контроллер, информацию которому доставляю через всплывающие события собственной структуры. Внутри - вся необходимая информация. Если все объекты созданы правильно, проблемы со всплытием нет.

Модальные окна, если это необходимо, прибиваю внизу. В момент обработки клика по кнопке и отправки наверх события.

s8000_1 04.07.2010 21:49

Методом проб и ошибок пришел к наиболее удобному для себя виду:

Код AS3:

click="AppGlobal.controller.openWindow(something)"

А в самом контроллере в функции openWindow:
Код AS3:

AppGlobal.view.windowContainer.open(something)

и всякие другие действия по открытию окна.

По сути синглтон. Контролировать приложение намного проще, чем делать 100500 разных событий или явно передавать ссылку.

UPD. И для попапов удобно делать методы типа show() и hide(). Поэтому конкретный попап можно открыть так:
Код AS3:

var popUp = new TitleWindow();
popUp.show()


Котяра 04.07.2010 22:06

жесть. и причем здесь тогда controller и view? такой подход это абсолютно не MVC.
лучше просто
Код AS3:

click="dispatchEvent(new WindowEvent(WindowEvent.OPEN,something))"
//а в контроллере
addEventListener(WindowEvent.OPEN,windowContainer_open);
..
private function windowContainer_open(e:WindowEvent){
windowContainer.open(e.something)// хотя я бы назвал e.windowID
}

и не надо 100500 событий - достаточно одного с разными параметрами..
А в класс события WindowEvent можно добавить еще CLOSE, RESTORE,MAXIMIZE, MINIMIZE итп.. не плодя лишних классов

s8000_1 04.07.2010 22:15

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

Гораздо удобнее внутри вьювера автоматически подписать себя на апдейты любой модели через глобальные статические переменные и управлять моделями через глобальный контроллер.

В вашем коде как минимум должен быть +1 контроллер, в котором присутствует ссылка на вьювер. Смысл создавать его? Только чтобы слепо следовать шаблону MVC?
А что если вьювер не на сцене (ну там, окошко плавно исчезло, после того, как исчезло надо что-то сделать)? Тогда что, свой диспатчер писать? Задача переусложняется.

Котяра 04.07.2010 22:23

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

s8000_1 04.07.2010 22:30

Котяра, это в теории. На практике проблемы от того, что вьювер знает о чем-то глобальном, возникают в 1% случаев. Через статики управлять флэшкой проще, чем каждый вьювер извне подписывать, отписывать, создавать кучу кастомных событий типа BUTTON_SUBMIT (а это очередная связка - про событие знает и контроллер. и вьювер, в одном dispatch в другом addEventListener), передавать ссылку на модель для функции update и др.

В моем подходе кода меньше, логика более прозрачна. А уж как называть его MVC или BAD MVC без разницы. Автор спрашивал, как проще и удобнее, я ответил :)

Psycho Tiger 04.07.2010 22:59

Цитата:

Насчет MVC. Я понимаю, что у каждого вьювера должен быть контроллер, подписывающий его на апдейты модели и управляющий моделями.
Неа, зачем? У вьюшки есть только модель, контроллера может и не быть. Другое дело, что и модель в таком случае излишне, как и излишен весь MVC.
Цитата:

нужно динамически создавать контроллеры, в них вьюверы
Её можно и не в контроллере делать :)
Цитата:

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

Цитата:

А что если вьювер не на сцене (ну там, окошко плавно исчезло, после того, как исчезло надо что-то сделать)? Тогда что, свой диспатчер писать? Задача переусложняется.
Ну э, контроллеру в принципе плевать, есть stage у вьюшки или нету. Или я не о том?
Цитата:

Котяра, это в теории. На практике проблемы от того, что вьювер знает о чем-то глобальном, возникают в 1% случаев.
А это уже сродни инкапсуляции. Идеальный программист в вакууме может её вообще не делать - и всё будет замечательно. Чем меньше доступно действий - тем меньше шансов что-то поломать. Вот и вся философия. Если у меня всё управляется статикой - пусть, но пусть оно стоит того. Тут не стоит, но я тему не сильно читал)

Котяра 04.07.2010 23:37

Цитата:

Сообщение от s8000_1 (Сообщение 919868)
Котяра, это в теории. На практике проблемы от того, что вьювер знает о чем-то глобальном, возникают в 1% случаев. Через статики управлять флэшкой проще, чем каждый вьювер извне подписывать, отписывать, создавать кучу кастомных событий типа BUTTON_SUBMIT (а это очередная связка - про событие знает и контроллер. и вьювер, в одном dispatch в другом addEventListener), передавать ссылку на модель для функции update и др.

Да Бог с Вами.. Просто я увидел в Вашем коде
click="AppGlobal.controller.openWindow(something)
AppGlobal.view.windowContainer.open(something)

а это соооооовсем не MVC.

Цитата:

Сообщение от s8000_1 (Сообщение 919868)
В моем подходе кода меньше, логика более прозрачна. А уж как называть его MVC или BAD MVC без разницы. Автор спрашивал, как проще и удобнее, я ответил :)

Проще и удобнее? Логика прозрачнее ? Вряд-ли это так..
Писатель вьюшек должен знать о : AppGlobal.controller.openWindow(something) ? Не проще ли просто слать события опеделённого типа..
Подход через глобальные переменные - плохой подход и использование его должно иметь очень сильные оправдания.

s8000_1 05.07.2010 00:40

Котяра, я использую этот подход для UI, который в большинстве случаев пишет один человек полностью)

А для игрового процесса, с подгружаемыми персонажами на карту, например, правильное MVC, ибо внешняя swfка ничего и не может знать о родителе.


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

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