PDA

Просмотр полной версии : AIR и 2 класса (MovieClip, NativeWindow)


Milyh
19.04.2012, 01:31
Имеетсяч приложение на air. Есть главный класс Main, расширяющий MovieClip, и есть класс ExportWindow, расширяющий NativeWindow. Задача в классе ExportWindow вызвать метод из Main. Додумался в конструкторе передавать параметр класс, от куда будет браться ссылка:
public function ExportWindow(mainClassLink:Main, messege:String)
Но выглядит не очень красиво. Подскажите как сделать.

RJ Presto
19.04.2012, 01:36
например, главный класс можно сделать синглтоном
http://gskinner.com/blog/archives/2006/07/as3_singletons.html
http://garbage-collector.ru/2007/10/singleton_in_actionscript_3.html

Milyh
19.04.2012, 01:53
По моему не лучшее решение

RJ Presto
19.04.2012, 01:56
не могу сказать, насколько хорошо это решение, не зная структуру вашего проекта.
еще можно сделать метод статичным или передавать аргументом непосредственно метод, который нужно вызвать.

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

Milyh
19.04.2012, 02:03
В Main имеется функция закрывающая все окна и само собой приложение

package
{
import ...

public class Main extends MovieClip
{
...

// Закрытие программы
public function closeApplication(e:Event = null):void
{
var windowsArray:Array = NativeApplication.nativeApplication.openedWindows;

for (var i:int = 0; i < windowsArray.length; i++)
windowsArray[i].close();
}
}
}


А в ExportWindow, просто есть окно с кнопкой, выполняющей закртие всех окон/приложения

package src.windows
{
import ...;

public class ExportWindow extends NativeWindow
{
public function ExportWindow(mainClassLink:Main, messege:String)
{
button.addEventListener(MouseEvent.CLICK, mainClassLink.closeApplication); // Закрытие приложения

}
}

}

expl
19.04.2012, 02:20
К чему вы этот код привели?

Есть какой-то экземпляр класса Main
Есть какое-то окно ExportWindow

1. Если есть уверенность, что ситуации, когда main не существует, а ExportWindow существует быть не может - можно передать в конструкторе, не вижу здесь ничего некрасисовго
2. Если main может отсутствовать - нужен третий объект, владелец этого main, и этого владельца передаём в конструктор. Можно слать события при появляении main у владельца, если ExportWindow надо на это реагировать (подняли окно - подписались, опустили - отписались)
3. Ещё можно при создании main проверять, существует ли ExportWindow (а если он не один... весело будет) и присваивать exportWindow.main = main, если существует. А если создаем ExportWindow, тоже проверять существует ли main и присваивать. Вобщем, метод - не фонтан.
4. Сделать Main синглтоном. Получаем что-то среднее между 1-м и 2-м вариантом, только лишаемся возможности контроля над временем создания этого Main. Плюс этот Main светит глобальной точкой доступа на всё приложение и не даёт создать свой второй экземпляр. Оно нам надо?
5. Фантазия не имеет границ, можно моного всего придумать с событиями, шиной событий, регистрами объектов, IoC-контейнерами, но, думаю, стоит остановиться.

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

maxkar
19.04.2012, 08:22
Ну и зачем вам передавать ссылку на Main? Это действительно выглядит плохо. Передайте ссылку на функцию Main.closeApplication, ведь нужна только она.

Art_133
19.04.2012, 09:54
1. Диспачте событие из ExportWindow.
2. Ловите его в классе Main.
Зачем все усложнять?:)

Milyh
19.04.2012, 12:13
1. Диспачте событие из ExportWindow.
2. Ловите его в классе Main.
Зачем все усложнять?:)
Можно пример?

expl
19.04.2012, 13:00
Пример:

package src.windows
{
import ...;

public class ExportWindow extends NativeWindow
{
public function ExportWindow(mainClassLink:Main, messege:String)
{
button.addEventListener(MouseEvent.CLICK, onButtonClick); // Закрытие приложения

}
private function onButtonClick(event:MouseEvent):void
{
dispatchEvent(new ExportWindowEvent(ExportWindowEvent.BUTTON_CLICK));
}
}

}

При поднятии окна подписываться на него и в обработчике дергать нужный метод Main.

Milyh
19.04.2012, 17:45
Я так понимаю если в Main написать:

ExportWindow.addEventListener(ExportWindowEvent.BUTTON_CLICK, function);
ExportWindow.button.addEventListener(MouseEvent.CLICK, function);

Будет одно и тоже, только разная реализация?

RJ Presto
19.04.2012, 18:00
первый вариант правильнее, так как вы не завязываетесь на внутреннюю структуру ExportWindow.
если завтра вам надо будет это событие отправлять по нажатию на другую кнопку - вы только добавите dispatchEvent в еще одно место, а не кучу подписчиков еще и на вторую кнопку.

expl
19.04.2012, 23:39
Первый вариант гибше гораздо.
Приходилось наблюдать в проекте, как народ лезет во внутренности окошек - в коде очень тяжело было разобраться и вдвойне тяжело вносить правки. И после объяснения "почему так делать не надо" и рефакторинга всё стало гораздо лучше.
Но, как всегда, каждый проект уникален и, возможно, Вы не огребёте. А может даже и лучше будет.

Milyh
20.04.2012, 02:29
Ошибку даёт: неизвестный параметр ExportWindowEvent

RJ Presto
20.04.2012, 11:13
вы должны создать новый класс для своего события, отнаследовав его от Event

package events
{
import flash.events.Event;

public class ExportWindowEvent extends Event
{
public static const BUTTON_CLICK:String = 'buttonClick';

public function ExportWindowEvent(type:String)
{
super(type, true);
}
}
}


затем в ExportWindow после определенного действия вы вставляете вызов

dispatchEvent(
new ExportWindowEvent(
ExportWindowEvent.BUTTON_CLICK
)
);

Milyh
20.04.2012, 21:55
Спасибо, разобразся

expl
21.04.2012, 22:18
вы должны создать новый класс для своего события, отнаследовав его от Event

package events
{
import flash.events.Event;

public class ExportWindowEvent extends Event
{
public static const BUTTON_CLICK:String = 'buttonClick';

public function ExportWindowEvent(type:String)
{
super(type, true);
}
}
}


Если не переопределить метод clone, то при баблинге или повторном распространении событие внезапно превратится в тип Event, а не ExportWindowEvent (и свалится там, где вы ожидали ExportWindowEvent). Лучше так:

package events
{
import flash.events.Event;

public class ExportWindowEvent extends Event
{
public static const BUTTON_CLICK:String = 'buttonClick';

public function ExportWindowEvent(type:String)
{
super(type, true);
}

override public function clone():Event
{
return new ExportWindowEvent(type);
}
}
}