PDA

Просмотр полной версии : Обращение к родительскому SWF


greenhill
16.03.2011, 11:18
Здравствуйте, подскажите, пожалуйста, как из дочернего SWF можно обратиться к переменным,классам и функциям родительского SWF?

Коротко: есть контейнер, куда с помощью Loader() подгружается SFW, которая должна получить данные у родителя(контейнера)

Спасибо

etc
16.03.2011, 15:58
Сделайте публичный метод в руте загружаемого и вызовите из загрузчика, передав необходимые данные.

bav
16.03.2011, 16:18
(Ну не пропадать же написанному)

1) Можно через свойство parent (http://help.adobe.com/ru_RU/AS3LCR/Flash_10.0/flash/display/DisplayObject.html#parent), но это моветон.
2) Когда заканчивается загрузка SWF (по событию Event.COMPLETE) можно привязать Loader.content (http://help.adobe.com/ru_RU/AS3LCR/Flash_10.0/flash/display/Loader.html#content) к переменной родительского контейнера, приведя content или к типу главного класса загружаемой swf или к MovieClip (если главный класс унаследован от него). Далее можно в какую-нибудь функцию init(host:MovieClip), описанную в загружаемой флешке, передать ссылку на контейнер и узнавать через нее необходимую информацию.
3) Совсем правильным подходом будет организация взаимодействия родителя с ребенком посредством событий. Впрочем, все зависит от постановки задачи. Простая схема подобного взаимодействия: у ребенка есть методы, с помощью которых родитель может отдавать ему какие-нибудь данные. Родитель, загрузив ребенка, подписывается на прослушку событий CustomEvent.GIVE_ME_DATA, исходящих от ребенка. Ребенок, когда ему что-нибудь нужно делает dispathEvent(new CustomEvent(CustomEvent.GIVE_ME_DATA)), родитель это дело слышит и отдает ребенку нужные данные.

ZergMaster
16.03.2011, 17:52
недавно узнал, что передачу простых переменных можно осуществлять по типу flashvars;
при загрузке ребенка в родителе пишем:

loader = new Loader();
loader.load(new URLRequest('myChild.swf?var1=something,var2=anything));

а ребенке получаешь эти переменные как обычные flashvars:

trace(loaderInfo.parameters['var1']);
trace(loaderInfo.parameters['var2']);

это, правда, оффтоп...
А по сабжу - я обычно пользуюсь методом, как описал bav под номером 2. Ща попробую события, давно хотел научиться)

Добавлено через 36 минут
bav, а не могли бы вы написать простенький пример кода, как осуществить событийное взаимодействие?

bav
17.03.2011, 00:35
// Загружающая флешка
package
{
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;

public class TestProject extends Sprite
{
private static const SWF_URL:String = "Temporary.swf";
// Создадим переменную типа MovieClip для хранения
// ссылки на загруженную флешку. Сделаем вид, что мы
// не знаем каков ее главный класс.
private var _loadedSWF:MovieClip;
private var _loader:Loader;

public function TestProject():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(event:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// Начинаем загрузку флешки
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleteHandler);
_loader.load(new URLRequest(SWF_URL));
}

private function loaderCompleteHandler(event:Event):void
{
// Сохраняем ссылку на загруженное.
_loadedSWF = _loader.content as MovieClip;
// Подписываемся на прослушку событий.
_loadedSWF.addEventListener(Event.COMPLETE, childCompleteHandler);
// Добавляем клип в список отображения. Это спровоцирует
// рассылку им события, которое мы готовы перехватить.
this.addChild(_loadedSWF);
}

/**
* Слушатель детских заявлений.
* @param event
*/
private function childCompleteHandler(event:Event):void
{
trace("Master: what do you want from me?");
_loadedSWF.setColor(0xABCDEF);
}
}
}


// Загружаемая флешка
package
{
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.display.Shape;
import flash.events.Event;

public class Temporary extends MovieClip
{
private var _circle:Shape;
public function Temporary():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(event:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// В данном случае используется существующее событие
// Event.COMPLETE. Разумеется можно определить любое свое.
// Событие рассылается сразу после добавления экземпляра
// Temporary в список отображения.
dispatchEvent(new Event(Event.COMPLETE));
}

/**
* Этот метод будет вызываться из родительского клипа.
* @param value Цвет кружка
*/
public function setColor(value:uint):void
{
_circle = new Shape();
var g:Graphics = _circle.graphics;
g.beginFill(value);
g.drawCircle(50, 50, 50);
g.endFill();
this.addChild(_circle);
trace("Temporary: you colored me, my Master!");
}
}
}


В данном случае мы наследуем класс Temporary от MovieClip, что позволяет впоследствии обращаться к методам клипа через оператор ".". Если мы попробуем унаследоваться от Sprite, во время выполнения вылезет ошибка: TestProject.as(51): col: 24 Error: Call to a possibly undefined method setColor through a reference with static type flash.display:Sprite.
Ключевое слово - "static". С MovieClip подобного не происходит, потому что это динамический класс. Хоть в хелпе по классу MovieClip нет метода setColor, дебагер не кричит, а честно пытается найти у загруженного клипа обозначенное динамическое свойство (метод). В чем ему сопутствует удача.
В случае наследования от Sprite выйти из ситуации можно, обратившись к методу следующим образом:
_loadedSWF["setColor"](0xABCDEF);
Прошу более опытных товарищей поправить меня, если я где-то ошибся.

Добавлено через 9 минут
Разумеется, у ребенка при таком подходе найдется не одно только желание COMPLETE. У него их будет много:
- Папа, хочу конфету!
- На тебе конфету.
- Хочу шариков!
- На тебе шариков.
- Папа, а сколько у тебя детей? И дай мне ссылку на сокет!
- Вместе с тобой - 43. А ссылку не дам, сокет детям не игрушка.