Форум 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=204193)

Fogflasher 22.10.2013 14:09

Композиция: обращение вверх по иерархии
 
Всем привет.

Вот здесь Wolsh вкратце описал принципы видимости свойств и методов.

Однако, некоторые практические следствия из этого мне неочевидны.

Рассмотрим на примере. Есть два класса ClassA (он же документ-класс), и ClassB.
ClassA содержит в себе экземпляр ClassB, то есть получаем простейший пример композиции.

ClassA.as:
Код AS3:

package
{
        import flash.display.*;
 
        //--- ClassA ---//
        public class ClassA extends Sprite
        {
                public var classA_sv1:String = "Свойство1 класса А";
 
                //--- Constructor ---//
                public function ClassA()
                {
 
                        trace("<<< Экземпляр класса ClassA создан >>>");
 
                        classB = new ClassB(); //создаем экземпляр класса B
                        trace(classB.classB_get(2)); //обращаемся к свойствам ClassB через его же метод
 
                //--- Method: classA_get() ---//
                public function classA_get()
                {
                        trace("Возвращено:");
                        return classA_sv1;
                }
 
        }
 
 
}

ClassB.as:
Код AS3:

package
{
        import flash.display.*;
 
        //--- ClassB ---//
        public class ClassB extends Sprite
        {
 
                private var classB_sv1:String = "Свойство1_класса_B";
                private var classB_sv2:String = "Свойство2_класса_B";
 
                //--- Constructor ---//
                public function ClassB()
                {
 
                        trace("((( Экземпляр класса ClassB создан )))");
 
 
                }
                //--- Method: classB_get() ---//
                public function classB_get(n:uint):String
                {
 
                        if (n == 1)
                        {
                                trace("Возвращено:");
                                return classB_sv1;
 
                        }
                        else if (n == 2)
                        {
                                trace("Возвращено:");
                                return classB_sv2;
 
                        }
                        else
                        {
                                trace("Возвращено:");
                        }
 
                        return "Cвойство неопределено";
 
                }
        }
 
}

В такой форме всё работает, и мы получаем:
Цитата:

<<< Экземпляр класса ClassA создан >>>
((( Экземпляр класса ClassB создан )))
Возвращено:
Свойство2_класса_B
А теперь, например, нужно реализовать еще две задачи, связанные с обращением "снизу вверх".

1. Обратиться из конструктора ClassB к свойству classA_sv1 (или методу classA_get()) класса ClassA.
2. Обратиться из конструктора ClassB к самому экземпляру ClassA.

1. По первой задаче, я пробовал в конструкторе ClassB вот такие строки:
Код AS3:

trace("classA_sv1 = ", classA_sv1); //ERROR: 1120: Access of undefined property classA_sv1.
trace("classA_sv1 = ", classA_get()); //ERROR: 1180: Call to a possibly undefined method classA_get.

C соответвующими результатами в комментариях.

2. По второй задаче, у меня что-то даже нет идей. Имя экземпляра документ-класса мы не знаем...
Вероятно, нужны какие-то специальные приемы, типа оператора super().

Wolsh 22.10.2013 15:17

Цитата:

А теперь, например, нужно реализовать еще две задачи, связанные с обращением "снизу вверх".
Не нужно. Нет никакой нужды экземпляру обращаться к родителям, иметь на них ссылку и дергать их методы. Такой ребенок очень плох. Ребенок не может выбирать себе родителей; ребенок должен быть спроектирован так, чтобы любой другой класс мог стать его родителем (то есть использовать его в своих целях), не создавая при этом целый завод методов и свойств для ублажения такого ребенка. Представьте, что класс Math, например, требовал бы для его использования в Ваших классах создавать специальные методы и публичные свойства для обеспечения своей работы. Смешно? Вспомните, есть ли хоть один класс во всей родной библиотеке, который бы требовал подобного — наличия определенных свойств и методов у использующего его класса.
Если же сильно приспичило обратиться к Документ-классу, и никакой нормальной архитектуры в голову не приходит, можете смело пользоваться ссылкой root из любого ДисплейОбжекта.

Fogflasher 22.10.2013 15:45

Хм, оказывается здесь я допустил концептуальную ошибку, занятно.
Благодарю также за подсказку насчет .root, поэкспериментируем, тем более что "грамотная архитектура" наверное означает знание Program Patterns.
Но на данный момент это не мой уровень, хотя некоторое самое общее представление о каждом у меня есть. Кстати, интересный вопрос: какой паттерн обычно получается у нубов (или хотя бы ближе всего по структуре), только начинающих юзать композиции и наследования? Или у тех кто пишет чисто в Main.
Наверное все-таки Singleton.

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

udaaff 22.10.2013 16:27

Код AS3:

private function this_mouseDownHandler(event:MouseEvent):void 
{
        //очищаем весь список отображения
        trace(this.parent.removeChildren());
}

Так делать не надо. Кнопка, как уже было сказано, ничего не должна знать о родителе. Иначе это связывает классы.

Akopalipsis 22.10.2013 16:31

Цитата:

Иначе это связывает классы.
Тогда у меня два вопроса -
Почему она в данном контексте связывает, ведь она не чего не знает о родителе.
И как тогда делать? Ловить в MainView клик от кнопки и обрабатывать как родителю хочется?

udaaff 22.10.2013 16:33

Цитата:

ведь она не чего не знает о родителе.
Вызывает метод родителя.
Цитата:

Ловить в MainView клик от кнопки и обрабатывать как родителю хочется?
Да.

UDP: Сможете ли вы это кнопку использовать в какой-то другой программе? Нет, потому что она завязана с другим классом, может быть и косвенно. Кнопка должна выполнять функции кнопки, не более того. По крайней мере тут.

Wolsh 22.10.2013 16:35

Цитата:

тем более что "грамотная архитектура" наверное означает знание Program Patterns
Обычно умения пользоваться Событиями достаточно.
Если родителю нужно, он подписывается на события от ребенка. Таким образом ребенок может сказать "Папа, меня Вася побил!" и папа примет решение на основании своих соображений. Создавать ситуацию, когда ребенок требует "Папа.убей(Васю)" нарушает самые примитивные представления об иерархии. Всегда родитель распоряжается ребенком, никогда наоборот. Родитель создал ребенка для решения каких-то своих задач, ребенок не должен знать ни этих задач ни своего родителя. Должен просто хорошо делать свою работу, а родитель должен предоставить ему все необходимое для этой работы при создании или, по крайней мере, до того как требовать результат.

Добавлено через 6 минут
Кнопка не может содержать в себе код, делающий что-то не с кнопкой или ее детьми. Никогда.
"Кнопка" это то, что нажимается, а не то, что удаляет все объекты со стейджа. Все, что должна уметь кнопка — нажиматься. Такую кнопку можно использовать в любом проекте, потому что она просто делает СВОЮ работу. Разносить логику, касающуюся всех, по всем мелким детишкам проекта еще хуже, чем писать код в отдельных кадрах мувиклипов.

udaaff 22.10.2013 16:53

А для чего новое событие изобретать?

Akopalipsis 22.10.2013 16:57

Цитата:

А для чего новое событие изобретать?
А как тогда? Передиспатчивать евент?

udaaff 22.10.2013 16:59

В MainView подписывайтесь на MOUSE_DOWN. Из кнопки убирите обработчик.

Akopalipsis 22.10.2013 17:03

А если кнопок будет много ( как например калькулятор ) это Вы предлагаете для каждой писать слушателя, в место наследования от класса у которого всё уже прописано? я не согласен.

udaaff 22.10.2013 17:07

Ну так вы же в итоге всё равно подписываетесь, только на другое событие.
Цитата:

А если кнопок будет много
Опять же от задачи зависит. Если надо будет, то для каждой пропишу =)

Akopalipsis 22.10.2013 17:13

udaaff Спасибо за обьяснения!
Хотя ещё можно и destroy сразу вызывать.
Код AS3:

package 
{
        import flash.display.DisplayObject;
        import flash.display.Sprite;
        import flash.events.Event;
 
        public class Main extends Sprite
        {
                public function Main()
                {
                        if (stage) init();
                        else addEventListener(Event.ADDED_TO_STAGE, init);
                }
 
                private function init(e:Event = null):void
                {
                        removeEventListener(Event.ADDED_TO_STAGE, init);
                        new AppConfig(this);
                }
        }
 
}

Код AS3:

package 
{
        import flash.display.DisplayObjectContainer;
 
        public class AppConfig
        {
                private var _doc:DisplayObjectContainer;
                private var _view:MainView;
 
                public function AppConfig(doc:DisplayObjectContainer)
                {
                        //сохраняем ссылку на DisplayObjectContainer
                        _doc = doc;
                        //создаём главный класс отображения
                        _view = new MainView();
                        //добавляем его в DisplayObjectContainer
                        _doc.addChild(_view);
                }
 
        }
 
}

Код AS3:

package 
{
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
        public class MainView extends Sprite
        {
                private var _button:Button;
                private const DESTROY:uint = 0xA7A7A7;
 
                public function MainView()
                {
                        _button = new Button();
                        _button.addEventListener(MouseEvent.MOUSE_DOWN, button_mouseDownHandler);
                        _button.id = DESTROY;
                        _button.x = _button.y = 100;
                        this.addChild(_button);
                }
 
                private function button_mouseDownHandler(event:MouseEvent):void
                {
                        if (event.target.id == DESTROY) this.destroy();
                }
                private function destroy():void
                {
                        super.removeChildren();
                }
 
        }
 
}

Код AS3:

package
{
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
 
        public class Button extends Sprite
        {
                private var _id:uint;
 
                public function Button()
                {
                        super();
                        if (stage) init();
                        else addEventListener(Event.ADDED_TO_STAGE, init);
                }
 
                private function init(event:Event=null):void
                {
                        removeEventListener(Event.ADDED_TO_STAGE, init);
 
                        super.graphics.beginFill(0x000000);
                        super.graphics.drawRect(0, 0, 70, 45);
                        super.graphics.endFill();
                }
 
                public function get id():uint
                {
                        return _id;
                }
 
                public function set id(value:uint):void
                {
                        _id = value;
                }
 
        }
 
}


Fogflasher 22.10.2013 17:50

Wolsh, ясно, значит обращение вверх по иерархии вообще ересь, и нужно менять архитектуру.

Akopalipsis, о как интересно, благодарю за пример. Чуть позже попробую протестировать, но уже при беглом осмотре имеется пара вопросов.
Но пока только хотел спросить, а что это за подход такой с MainView, почему вы его в диалоге с udaff использовали как отдельный термин?
Это часть какого-то Паттерна? Может у вас тут вообще MVC реализовано.

Babylon 22.10.2013 18:02

Обращение вверх по иерархии не ересь. Допустим если у вас одинаковое содержимое в разных контейнерах. Я для этих целей использую сами знаете что.

Akopalipsis 22.10.2013 18:10

Цитата:

Это часть какого-то Паттерна?
Проще всего представить это как диафильм. Есть класс, который отвечает только за
отображение, он создаёт и обрабатывает только визуальные обьекты.
Когда мне в первые показали такой вариант, то я его боялся и не использовал очень долго.
Но сейчас я не даже представить не могу, что буду использовать другую реализацию.
Цитата:

Я для этих целей использую сами знаете что.
Сигналы?)

Wolsh 22.10.2013 19:01

Цитата:

if (event.target.id == DESTROY) this.destroy();
Не надо target. id это свойство Button. Вы же подписывались на событие от _button, а это .currentTarget
Мало того, если _button член класса, как в данном коде, id вообще не нужен.
Код AS3:

if (event.currentTarget == _button) this.destroy();

И не заводите привычку подписывать кнопки на даун. Только клик. Юзер должен иметь возможность передумать.

Akopalipsis 22.10.2013 19:05

Вот я и говорю, что destroy можно сделать слушателем.

Babylon 22.10.2013 20:20

У меня есть dict[node.@id]=class

Fogflasher 23.10.2013 00:19

Akopalipsis, разбираю ваш пример, идея прикольная, но и вопросов много )


1.
Код AS3:

private function init(e:Event = null):void

Зачем здесь прописывать дефолтный null, это чем то лучше, чем оставить просто e:Event?
А разве по умолчанию оно и не будет равно null? Или тут есть какой-то ньюанс...


2.
Код AS3:

new AppConfig(this);

Как доступно для нуба озвучить смысл сего оператора?
Я понимаю его так: Создать экземпляр класса AppConfig и передать ему экземпляр класса Main.
Правильно ли это? И кстати, это пример Композиции? Видимо это пример "Недокомпозиции", так сказать...
Ведь мы этот оператор не присваиваем никакой переменной, то есть экземпляр завис в воздухе.


3.
Код AS3:

_doc.addChild(_view);

Правильно ли я понимаю, что по сути мы сейчас добавили экземпляр класса MainView в экземпляр класса Main?
И именно для этого писали new AppConfig(this); то есть передача через конструктор обязательна. И по другому нельзя.


4.
Код AS3:

private var _button:Button;

Сначала я было подумал, что мы будем юзать некий системный класс Button, потому что это слово подсвечивается.
Однако потом увидел, что ваш четвертый класс имеет такое же имя... Это смущает.
То есть, выходит, создав свой класс Button мы как бы оттенили системный класс с таким же именем.
Этакий классовый оверрайд?


5.
Код AS3:

_button.id = DESTROY;

А вот этот .id - это что за свойство, оно же не было ранее объявлено нигде.
Или это какой-то трюк, типа, мы можем налету присобачить к экземпляру любые свойства?


6.
Код AS3:

this.destroy();

Хм, как-то цельное понимание не складывается. То есть мы сделали следующее:
Применили к текущему экземпляру класса MainView метод destroy, который обратился к экземпляру класса выше
(то есть super. это ссылка на Main, ведь так?), и удалил всех его детей. Выходит, это всё равносильно записи: this.super.removeChildren();


7.
Код AS3:

public function Button() 
                {
                        super();                                                                       
 
                        //...
 
                }

Не понимаю, что здесь делает super(); Он вызывает конструктор системного класса Sprite, но... что это дает?
Это равносильно записи new Sprite(); так чтоли? Но даже если так, то экземпляр завис в воздухе, и мы его потеряли.
Тогда "... зачем ей все шелка?" (с)


8. Функции get и set, в связке со свойством _id, они несут какую-то функциональность в данном примере?
Похоже что нет... Видимо добавлены для "цельности концепций", поправьте, если это не так.


9. Вы проверяли этот проект на работоспособность? А то при запуске я получаю одну ошибку:
Цитата:

1061: Call to a possibly undefined method removeChildren through
a reference with static type flash.display:Sprite. super.removeChildren();

Babylon 23.10.2013 00:22

Зачем Вы разбили детские мечты об идеальном коде?

Fogflasher 23.10.2013 00:37

Babylon,
Цитата:

Я для этих целей использую сами знаете что.
Ээ... : ) Нет, боюсь что не знаю.

Цитата:

У меня есть dict[node.@id]=class
К сожалению, мне непонятна эта запись. Хотя догадываюсь из какой это области, всякие там Dictionary, ужас-ужас.

Цитата:

Зачем Вы разбили детские мечты об идеальном коде?
Такой цели я специально не ставил, лол.

Akopalipsis 23.10.2013 00:45

Цитата:

Зачем здесь прописывать дефолтный null, это чем то лучше, чем оставить просто e:Event?
Ну если не будет нуля, то не получится вызвать метод без параметров.
Цитата:

Я понимаю его так: Создать экземпляр класса AppConfig и передать ему экземпляр класса Main.
Во первых - передаём ссылку, ссылку - на DisplayObjectContainer.
Цитата:

Ведь мы этот оператор не присваиваем никакой переменной, то есть экземпляр завис в воздухе.
А он и не нужен, его цель только передать ссылку.
Цитата:

Правильно ли я понимаю, что по сути мы сейчас добавили экземпляр класса MainView в экземпляр класса Main?
И именно для этого писали new AppConfig(this); то есть передача через конструктор обязательна. И по другому нельзя.
Во первых - передаём ссылку, ссылку - на DisplayObjectContainer.
Можно, как Вы хотите так и можно. я просто показал как делает большинство.
Цитата:

Сначала я было подумал, что мы будем юзать некий системный класс Button, потому что это слово подсвечивается.
я не знаю что такое системный класс кнопки.
Цитата:

А вот этот .id - это что за свойство, оно же не было ранее объявлено нигде.
ID- это идентификатор.
Цитата:

Применили к текущему экземпляру класса MainView метод destroy, который обратился к экземпляру класса выше
(то есть super. это ссылка на Main, ведь так?), и удалил всех его детей. Выходит, это всё равносильно записи: this.super.removeChildren();
this === текущий
super === наследуемый
Цитата:

Не понимаю, что здесь делает super(); Он вызывает конструктор системного класса Sprite, но... что это дает?
Оно так и так там есть...
Цитата:

8. Функции get и set, в связке со свойством _id, они несут какую-то функциональность в данном примере?
Так лучше.
Код AS3:

Вы проверяли этот проект на работоспособность? А то при запуске я получаю одну ошибку:

Вами исправленный код - нет!

Добавлено через 4 минуты
Fogflasher я тоже мало чего знаю, но я всегда слушаю советы,
Вам нужно Мука почитать. Вот есть у Вас вопрос - что такое super, открыли и посмотрели.
Не поняли, спросили. я тоже уже кучу книг прочёл, но пока мне не скажут, что надо так! меня сомнения гложут.

Добавлено через 6 минут
Babylon на самом деле, я Вас теперь понимаю и понимаю Ваше слова про ядро. Странно что Вас другие не понимали.

Wolsh 23.10.2013 00:59

Цитата:

я просто показал как делает большинство.
Ни разу в жизни так не делал. Испытал оправданный ужас, глядя на висящий в воздухе вызов конструктора. Аж мурашки по коже.
Цитата:

А вот этот .id - это что за свойство, оно же не было ранее объявлено нигде.
Свойство класса Button, очевидно.

Цитата:

К сожалению, мне непонятна эта запись. Хотя догадываюсь из какой это области, всякие там Dictionary, ужас-ужас.
Dictionary + XML + e4x
Цитата:

Вы проверяли этот проект на работоспособность? А то при запуске я получаю одну ошибку:
Метод removeChildren требует 11 версии плеера.
Учитывая, что на дворе уже версия 11.9, может пора перестать компилить под десятку?

Akopalipsis 23.10.2013 01:04

Цитата:

Ни разу в жизни так не делал. Испытал оправданный ужас, глядя на висящий в воздухе вызов конструктора. Аж мурашки по коже.
А возможно я и не прав, Вы про то, что конфиг не сохранён?

Wolsh 23.10.2013 01:09

Цитата:

Вы про то, что конфиг не сохранён?
Я про то, что у GC сегодня сытный ужин)

elder_Nosferatu 23.10.2013 03:39

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

Wolsh 23.10.2013 09:34

Ну так это Stage. У него нет родителя и сам он не расширяется, так что командовать им могут только дети, как ни крути.

Fogflasher 23.10.2013 09:51

Akopalipsis,
Цитата:

Fogflasher я тоже мало чего знаю, но я всегда слушаю советы...
Звучит так, словно я не слушаю советы )

Цитата:

Вам нужно Мука почитать. Вот есть у Вас вопрос - что такое super, открыли и посмотрели.
Наверное вам показалось, что я придираюсь к вашему коду и троллю...
Отнюдь нет. Просто иногда приятнее спросить, нежели ковыряться в документации. Возможно я переборщил здесь.

Цитата:

я не знаю что такое системный класс кнопки.
Я тоже не знаю. Но раз подсвечивается, значит "что-то тут нечисто". Есть еще вот такое.

Цитата:

ID- это идентификатор.
Не, ну так смысл свойства понятен, базару нет.
Я имел ввиду: это свойство системное, ну типа x, или buttonMode, или созданное рукотворно, но "на лету", без объявление где либо еще.

Цитата:

Оно так и так там есть...
Нихт ферштэйн... Ну вот если бы там не было этого super(); что бы изменилось?

Цитата:

Вами исправленный код - нет!
Да я просто гремлин какой, ломающий чужие механизмы, и обвиняющий их создателя в неработоспособности ; )

Wolsh,
Цитата:

Метод removeChildren требует 11 версии плеера.
Учитывая, что на дворе уже версия 11.9, может пора перестать компилить под десятку?
Да, наверное таки пора : ) Хотя, тут есть встречный вопрос, вот когда я пробую открыть посредством Flash CS 3 файлы .fla более высокой версии, у меня идет сообщение: "неизвестный формат". Будет ли такое наблюдатся в обратном порядке, то есть смогу ли я открыть например версией CS6, файлы CS3?
И если нет, то можно ли как-то из библиотеки мувики экспортировать/передать в более старшую версию.

udaaff 23.10.2013 10:17

Цитата:

Ну вот если бы там не было этого super(); что бы изменилось?
Можно многие вещи не писать и это не повлияет на работу программы. Но лучше писать как принятно.

Fogflasher 23.10.2013 12:31

udaaff, то есть практически, его можно и не писать... хорошо, но вообще, замысел этой вставки в чем?

Просто дань традиции? Типа "раньше так было нужно, теперь уже нет, но почтим Велеса".

AlexLucas 23.10.2013 13:50

Если вы не вызовите super() в конструкторе, компилятор это сделает за вас, но добавит этот вызов в самое начало конструктора.
super() имеет смысл вызывать если вы хотите что-нибудь сделать до того как вызовется конструктор супер-класса.

Fogflasher 23.10.2013 14:09

AlexLucas, о как, интересно, но ведь в коде:

Код AS3:

public function Button() 
                {
                        super();
                        if (stage) init();
                        else addEventListener(Event.ADDED_TO_STAGE, init);
                }

Он и так стоит в начале конструктора.

И, если я вас правильно понял, здесь он нефункционален.
А вот если его поставить после if(stage)... то получается, что сначала выполнится if, а потом уже наш super(); и в этом есть уже некий замысел.
(просто проговорю вслух, чтобы закрепить: наличие рукописного super'a автоматически отменяет запуск призрачного системного супера).

AlexLucas 23.10.2013 14:12

Верно.
Раз. Два.

Akopalipsis 23.10.2013 15:45

AlexLucas а почему в примере выше, вызов конструктора супер класса, не функционально? Разве до вызова конструктора может появится стейдж?

AlexLucas 23.10.2013 16:05

Что с super() что без супер в том случае всё равно, я же написал
Код:

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

Fogflasher 06.11.2013 09:49

Цитата:

Сообщение от Wolsh (Сообщение 1149520)
Добавлено через 6 минут
Кнопка не может содержать в себе код, делающий что-то не с кнопкой или ее детьми. Никогда.
"Кнопка" это то, что нажимается, а не то, что удаляет все объекты со стейджа. Все, что должна уметь кнопка — нажиматься. Такую кнопку можно использовать в любом проекте, потому что она просто делает СВОЮ работу. Разносить логику, касающуюся всех, по всем мелким детишкам проекта еще хуже, чем писать код в отдельных кадрах мувиклипов.

Хм, кажется, я только щас начал понимать глубинный, мироточивый смысл этих слов.

Так что-же получается, в нашем кустомном классе Button вообще не должно быть никаких листенеров, вообще ничего?
Ну максимум, координаты, размеры, имя экземпляра, и всё...

Выходит, на весь проект (типа: ГУИ-интерфейс), должен быть некий единый глобальный слушатель, который находится в мега-родителе.
И он уже отсеивает по свойствам e.target (и другим), нужные действия?

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

Wolsh 06.11.2013 10:10

Цитата:

Так что-же получается, в нашем кустомном классе Button вообще не должно быть никаких листенеров, вообще ничего? Ну максимум, координаты, размеры, имя экземпляра, и всё...
Эммм.. Почему же? Кнопка должна нажиматься, реагировать на наведение мыши и уход. Это ЕЁ поведение, её функционал. Она может делать все что нужно ВНУТРИ себя, со своими детьми. А вот как раз "координаты" не являются ее собственным свойством, ибо это координаты в системе координат родителя, во внешнем мире. Родитель создал кнопку с какой-то известной ему целью и поместил туда, куда ЕМУ надо. И с размерами я бы тоже был осторожен, потому что такая "кнопка", самопроизвольно/неуправляемо/неожиданно прыгающая туда-сюда и меняющаяся в размерах естественно будет перекрывать другие объекты под ней или сталкиваться с ними. Размеры и координаты задает родитель; в случае ГУИ это какой-то лейаут, то есть класс, управляющий как раз размерами и координатами элементов.
Цитата:

дети должны наследоваться от EventDispatcher, а не от Sprite
Sprite является наследником EventDispatcher, вообще-то.
Цитата:

Выходит, на весь проект (типа: ГУИ-интерфейс), должен быть некий единый глобальный слушатель, который находится в мега-родителе.
И он уже отсеивает по свойствам e.target (и другим), нужные действия?
Ну зачем так-то... Кнопка может использоваться в других контролах, например в ВыпадающемСписке. Тогда слушать ее События будет её родитель — ВыпадающийСписок, а не какой-то ГлобальныйМенеджер))

Fogflasher 06.11.2013 15:47

Wolsh, спасибо, пока вопросов нет.

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

С генерацией кастомных событий не приходилось иметь дело, так что пока имеется неуверенность в этом вопросе.
Но то, что доступ вверх - от детей к родителям, должен происходить только посредством них, уже проясняет направленность в изучении этой темы.

Babylon 06.11.2013 16:28

Wolsh, ты предлагаешь каждому контейнеру или виду иметь список слушателей?


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

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