![]() |
|
||||||||||
|
|||||
|
Всем привет.
Например, у меня есть основной класс документа Main, где пишу весь основной скрипт. В него вложена некая панель BlackList. В панель вложено множество кнопок ItemBlackList. Вопросы такие: 1. Правильно ли, что я в классе ItemBlackList подписываюсь на события MOUSE_OVER и MOUSE_OUT, а CLICK слушаю в его родительском классе BlackList ? Как я понимаю - дочерний объект не должен влиять на родителя. Как правильно разграничить действия между родителем и дочерними объектами - что должен знать родитель, а что его ребенок? 2. По нажатию на любой из ItemBlackList, в файл blacklist.xml должны записываться некие данные. Но этот XML файл подгружен в классе Main. Как правильнее делать - передавать данные через всю цепочку ItemBlackList -> BlackList -> Main ?? Или же Main не обязан знать что нужно делать с файлом, а всю работу с файлом должен брать на себя класс BlackList ?? Не знаю - правильно ли делать так? И как в данном случае, например, узнать, какая из множества кнопок была нажата? Класс Main: blackList = new BlackList(); addChild(blackList); blackList.addEventListener("ITEM_BLACKLIST_CLICK", itemBlackListClick); private function itemBlackListClick(e:Event):void { trace("ITEM CLICK"); }
__________________
кто не отвечает, того garbage collector забирает |
|
|||||
|
Вам не обязательно думать, что должен знать родитель, а что ребёнок.
Достаточно просто представить проект как список объектов/компонентов. Вы пользуетесь ихними методами и свойствами и вас абсолютно не интересует, как они устроены внутри. Например, вы хотите добавить чекбокс. Напишите чекбокс(поле с галочкой), чтобы его можно было использовать вот так в любом проекте: var checkBox:CheckBox = new CheckBox(true, true); //(активен, значение флажка) checkBox.state = false; //снимаем галочку checkBox.enabled = false; //делаем чекбокс неактивным addChild(checkBox); //добавляем его в дисплейлист trace(checkBox.state); Да, вполне логично, что Цитата:
Можно в BlackList отправлять событие, что была нажата кнопка и сохранять какая именно кнопка в публичную переменную. Main пусть слушает BlackList и изменяет xml.
__________________
There is no thing in this world that is not simple. Последний раз редактировалось ZackMercury; 29.01.2015 в 03:47. |
|
|||||
|
Регистрация: Dec 2014
Сообщений: 312
|
Допустим есть три кнопки. По нажатию на первую рисуем квадрат, на вторую - треугольник, на третью - круг.
На Main addChild спрайт. А уже на этот спрайт addChild панель. Спрайт подписывается на события панели и рисует фигуры. PanelEvents.DRAW_SQUARE PanelEvents.DRAW_TRIANGLE PanelEvents.DRAW_CIRCLE Кнопка сама себя подписывает на CLICK. При клике диспатчит одно из событий панели. Либо панель подписывает конкретную кнопку на CLICK (но не себя). При клике диспатчит одно из событий панели. P.S. Но если вам нужно в xml гнать просто текст на кнопке. То можно и саму панель подписать на клик. Последний раз редактировалось callme; 29.01.2015 в 11:10. |
|
|||||
|
Как быть, если, например, вложенность намного больше и на самом главном уровне нужно ловить событие самого последнего вложенного объекта? На каждом уровне подписываться на событие ребенка и диспатчить его для родителя?
__________________
кто не отвечает, того garbage collector забирает |
|
|||||
|
Регистрация: Dec 2014
Сообщений: 312
|
Можно ловить событие, когда оно в фазе захвата.
Третий параметр в addEventListener(). package { import flash.display.Sprite; import flash.events.Event; public class Main extends Sprite { public function Main() { var sprite1:Sprite = new Sprite(); var sprite2:Sprite = new Sprite(); var sprite3:Sprite = new Sprite(); var sprite4:Sprite = new Sprite(); addChild(sprite1); sprite1.addChild(sprite2); sprite2.addChild(sprite3); sprite3.addChild(sprite4); sprite1.addEventListener('someEvent', sprite1_someevent, true); sprite4.dispatchEvent( new Event('someEvent') ); } private function sprite1_someevent(e:Event):void { trace("function sprite1_someevent()"); } } } |
|
|||||
|
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Лучше, конечно же, продумывать приложение иерархически, чтобы Императору не приходилось звонить каждому солдату в окоп и уж тем более наоборот. Разделяйте ответственность, назначайте командиров, устанавливайте порядок и направление отчетности. У каждого должна быть своя зона ответственности, и она определяется еще на уровне выделения Класса как сущности. В мире флэш это конечно немного не так абстрактно, из-за обилия визуальных объектов возникает некая растерянность, к кому/к чему "привязывать" логику. Надо всё же как-то разделить действия, ответственность, чтобы кнопка "только нажималась", панель кнопок "только сообщала о выборе", а решения принимал тот, кто эту панель кнопок и создал для интерфейса с пользователем. Если у Вас Мейн должен знать все о какой-то тридевятой кнопке в тридесятом контейнере, значит Вы не разделили ответственность по объектам и Мейн перегружен. Ему нужны министры, а министрам — менеджеры, организовывающие персонал. Создавайте цепочки иерархии, компануйте однотипные задачи, не валите все в одну кучу Мейн.
__________________
Reality.getBounds(this); |
|
|||||
|
Регистрация: Dec 2014
Сообщений: 312
|
Цитата:
Пример: В библиотеке Starling есть хранилище ассетов. Я кладу этот объект в глобальную переменную потому что мне придется обращаться к этому хранилищу много где. new MovieClip(globalAssetStore); Можно передавать этот assetStore в конструкторы, которые передадут этот объект во вложенные конструкторы. Но код становится нечитабельным. |
|
|||||
|
Цитата:
Кнопка не знает ничего о панели, она лишь знает свою функцию. Можно вызывать callBack() внутри кнопки, на который сделать сеттер onClick = someFunc; Но колбеки делают код неоднородным, а поэтому лучше подписываться на клик в двух местах - снаружи кнопки для того, чтобы знать, когда менять xml и внутри кнопки, чтобы к примеру менять визуальное отображение и состояние. Предлагаю сделать ещё интересней, package { import flash.display.Sprite; /** * ... * @author ZackMercury */ public class Panel extends Sprite { private static const OFFSET_BETWEEN_BUTTONS:int = 5; private var _buttons:Vector.<Button>; public function Panel() { _buttons = new Vector.<Button>(); } public function addButton(caption:String, onClick:Function):void { var btn:Button = new Button(caption); btn.onClick = onClick; addChild(btn); _buttons.push(btn); update(); } public function removeButton(caption:String):void { for (var i:int = 0; i < _buttons.length; i ++) { if (_buttons[i].caption == caption) { removeChild(_buttons[i]); _buttons.splice(i, 1); } } update(); } private function update():void { for (var i:int = 0; i < _buttons.length; i ++) { _buttons[i].y = (_buttons[i].height + OFFSET_BETWEEN_BUTTONS) * i; } } } } package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; /** * ... * @author ZackMercury */ public class Main extends Sprite { public function Main() { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } public function init(e:Event = null):void { if (hasEventListener(Event.ADDED_TO_STAGE)) removeEventListener(Event.ADDED_TO_STAGE, init); //entry var panel:Panel = new Panel(); panel.addButton("Start game", buttonClicked); panel.addButton("Exit", buttonClicked); panel.addButton("Options", buttonClicked); panel.removeButton("Options"); addChild(panel); } private function buttonClicked(e:MouseEvent):void { switch((e.target as Button).caption) { case "Start game": //начинаем игру break; case "Exit": //выходим из игры break; default: throw new Error("No action for this button"); } } } }
__________________
There is no thing in this world that is not simple. Последний раз редактировалось ZackMercury; 29.01.2015 в 22:39. |
|
|||||
|
Регистрация: Dec 2014
Сообщений: 312
|
to djken, я ошибся, надо делать как SuriTheAngel говорит.
Добавлено через 1 час 30 минут SuriTheAngel Мне кажется пусть лучше панель свои кнопки создает. Какие преимущества есть у твоего подхода? |
|
|||||
|
Это не мой подход, а подход с точки зрения Объектно-Ориентированного Программирования. (ООП)
Преимущества. Даже лень перечислять... 1) Можно эту же панель не переписывая использовать в любых других проектах, ведь кнопки создаются через методы addButton() и удаляются через removeButton() снаружи панели. 2) Логично, что панель выполняет лишь свои функции - является панелью, в которую можно добавить кнопки или удалить из неё кнопки. 3) Логично, что кнопки являются кнопками и выполняют лишь свою функцию, не меняют никаких xml. 4) Конечно, В КРАЙНЕМ СЛУЧАЕ, НУ ВДРУГ НУ ВООБЩЕ ППЦ КАК НАДА БУДИТ, можно создавать кнопки в панели, используя её же методы из конструктора =) Для справки) 5) Скачав классы Panel, Button не нужно лезть внутрь этих классов, чтобы знать как ими пользоваться. Достаточно написать var panel:Panel = new Panel(); напишите panel. И среда(FlashDevelop) сама подсказывает, какие есть методы у этого класса. И из их названий точно и ясно, что они делают. addButton() в переводе значит "добавить кнопку", для справки. removeButton() в переводе "убрать кнопку". набор передаваемых аргументов тоже достаточно ясно описан и подсказывается средой=) взгляните на код public function init(e:Event = null):void { if (hasEventListener(Event.ADDED_TO_STAGE)) removeEventListener(Event.ADDED_TO_STAGE, init); //entry var panel:Panel = new Panel(); panel.addButton("Start game", buttonClicked); panel.addButton("Exit", buttonClicked); panel.addButton("Options", buttonClicked); panel.removeButton("Options"); addChild(panel); } private function buttonClicked(e:MouseEvent):void { switch((e.target as Button).caption) { case "Start game": //начинаем игру break; case "Exit": //выходим из игры break; default: throw new Error("No action for this button"); } } Поэтому мы пишем набор инструментов, подобно классу Button(кнопка) или Panel(панель). При желании можно добавить классу Panel свойство orientation и 2 константы - Panel.HORIZONTAL, Panel.VERTICAL. Они будут определять, как будут располагаться кнопки - горизонтально или вертикально. Вот так вот мы и работаем) Улучшаем наши инструменты потихоньку. Потом мы можем в любой проект сунуть эти классы и они будут работать. Чтобы не копаться в их коде, мы пишем снаружи все обработчики кликов и пользуемся их свойствами и методами. P.S. Если хотите проверить, как будет работать код - могу ещё дописать класс Button ![]()
__________________
There is no thing in this world that is not simple. Последний раз редактировалось ZackMercury; 29.01.2015 в 22:39. |
![]() |
![]() |
Часовой пояс GMT +4, время: 00:26. |
|
|
« Предыдущая тема | Следующая тема » |
|
|