PDA

Просмотр полной версии : Как заставить работать dispatchEvent?


vvk80
07.11.2007, 20:02
Итак, есть два класса:
package
{
import flash.display.*;
import flash.events.*;

public class Test extends Sprite
{
private var evt:Event;

public function Test():void
{
trace("Test constructor called");
init();
}

private function init():void
{
evt = new Event("evt", true);
dispatchEvent(evt);
}
}

}

package
{
import flash.display.*;
import flash.events.*;

public class Main extends Sprite//document class
{
private var _test:Test;

public function Main():void
{
_test = new Test();
_test.addEventListener("evt", _onEvt);

}
private function _onEvt(evt:Event):void
{
trace("evt event called");
}
}

}

Не работает трейсер trace("evt event called");Почему он не работает, я вроде понимаю: event dispatchится до того ,как экземпляр класса на него подписался, и также понятно, что скорость загрузки такого класса мнгновенная, но елки палки, как все-таки заставить его сработать???

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

P.S. Если что нет так делаю, то подскажите как правильно, пожалуйста!:rolleyes:
Просто в жизни эти классы не такие уж маленькие, но смысл я думаю, я сохранил...

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

package
{
import flash.display.*;
import flash.events.*;

public class Test extends Sprite
{
private var evt:Event;
private var iconImg:BaseClass; //мой класс загрузки картинок и т.д.

public function Test():void
{
trace("Test constructor called");
init();
}

private function init():void
{
iconImg = new BaseClass(this,"firstPageDraft.png");
iconImg.initImg(0,0);
iconImg.addEventListener("loadComplete", _onIcoLoadComplete);
}
private function _onIcoLoadComplete(evt:Event):void
{
trace("_onIcoLoadComplete");
evt = new Event("evt", true);
dispatchEvent(evt);
}

}

}

P.P.S.
Пока нашел следующий workaround:
даже когда мне не нужно грузить картинку я ее все равно гружу, но потом делаю
iconImg = null, и все обнуляю, что еще надо обнулить...
Не знаю как там насчет производительности, но чувствую, что не очень...

vooparker
07.11.2007, 21:26
_test = new Test();
вот здесь выполняется конструктор и метод init тоже в котором и диспатчится событие. А подписываетесь вы на событие уже после.

PS. Если честно не понял в чем возникла проблема =)

†‡Paladin‡†
07.11.2007, 21:26
А ты
_test = new Test();
_test.addEventListener("evt", _onEvt);
местами менять непробовал?

LokiDi L0ck
07.11.2007, 21:45
местами менять непробовал?
...и попытаться подписать несуществующий объект =)))

†‡Paladin‡†
07.11.2007, 22:11
Подписаться на события от несуществующего объекта. Хотя ты прав не вариант.
Вот вариант:
package
{
import flash.display.*;
import flash.events.*;
import ITestAS3

public class Main extends Sprite//document class
{
private var _test:ITestAS3;

public function Main():void
{
_test = new ITestAS3();
_test.addEventListener("evt", _onEvt);
addChild(_test);
}
private function _onEvt(evt:Event):void
{
trace("was");
}
}

}

и

package
{
import flash.display.*;
import flash.events.*;

public class ITestAS3 extends Sprite
{
private var evt:Event;

public function ITestAS3():void
{
trace("Test constructor called");
init();
}

private function init():void
{
this.addEventListener(Event.ADDED, addedHandler);
}

private function addedHandler(e:Event):void {
evt = new Event("evt", true);
dispatchEvent(evt);
trace("EventDispatched");
}
}

}

vvk80
08.11.2007, 12:27
Подписаться на события от несуществующего объекта. Хотя ты прав не вариант.
Вот вариант:


Ты гений! Спасибо... Вроде заработало... но в моем реальном примере все оказалось сложнее... У меня событие ADDED, почему-то дублировалось и запускалось по несколько раз...

Копая хелп, обнаружил событие ADDED_TO_STAGE. Оно решило мою проблему. Все вроде заработало... Но, читая хелп, я не въехал в разницу между этими двумя событиями (отличия параметров bubbles и target я заметил)...
Если возможно, растолкуйте мне,пож-ста! :rolleyes:

etc
08.11.2007, 12:45
ADDED_TO_STAGE срабатывает тогда, когда спрайт появляется на сцене, а ADDED срабатывает тогда, когда спрайт цепляют к другому спрайту (ну или любому другому DisplayObjectContainer).

vvk80
08.11.2007, 13:33
ADDED_TO_STAGE срабатывает тогда, когда спрайт появляется на сцене, а ADDED срабатывает тогда, когда спрайт цепляют к другому спрайту (ну или любому другому DisplayObjectContainer).
спасибо, почти догнал :rolleyes:
в итоге следующий код
package
{
import flash.display.*;
import flash.events.*;


public class ITestAS3 extends Sprite
{
private var evt:Event;
private var child:Sprite;

public function ITestAS3(name:String=""):void
{
trace("Test constructor called");
this.name = name;
init();
//makeChild();
}

private function init():void
{
this.addEventListener(Event.ADDED, addedHandler);
}
private function makeChild():void
{
trace("Making child");
child = new Sprite();
this.addChild(child);
}
private function addedHandler(e:Event):void {
trace(this.name + " added to the display list");
evt = new Event("evt", true);
dispatchEvent(evt);

}
}

}

package
{
import flash.display.*;
import flash.events.*;
import ITestAS3;

public class Main extends Sprite
{
private var _test:ITestAS3;
private var _test2:ITestAS3;
private var _test3:ITestAS3;
private var _test4:ITestAS3;


public function Main():void
{
_test = new ITestAS3("Test1");
_test.addEventListener("evt", _onEvt);
trace("Test 1 adding to the display List");
addChild(_test);

}
private function _onEvt(evt:Event):void
{
trace("evt event called: processing next instance");
_test2 = new ITestAS3("Test2");
_test2.addEventListener("evt", _onEvt2);
trace("Test 2 adding to the display List");
addChild(_test2);
}

private function _onEvt2(evt:Event):void
{
trace("evt event called: processing next instance");
_test3 = new ITestAS3("Test3");
_test3.addEventListener("evt", _onEvt3);
trace("Test 3 adding to the display List");
addChild(_test3);
}
private function _onEvt3(evt:Event):void
{
trace("Final!!!");
trace(this.numChildren);
}
}

}
дает следующий output
Test constructor called
Test 1 adding to the display List
Test1 added to the display list
evt event called: processing next instance
Test constructor called
Test 2 adding to the display List
Test2 added to the display list
evt event called: processing next instance
Test constructor called
Test 3 adding to the display List
Test3 added to the display list
Final!!!
3


если открыть makeChild()
public function ITestAS3(name:String=""):void
{
trace("Test constructor called");
this.name = name;
init();
makeChild();
}

output будем следующим:
Test constructor called
Making child
Test1 added to the display list
Test 1 adding to the display List
Test1 added to the display list
evt event called: processing next instance
Test constructor called
Making child
Test2 added to the display list
Test 2 adding to the display List
Test2 added to the display list
evt event called: processing next instance
Test constructor called
Making child
Test3 added to the display list
Test 3 adding to the display List
Test3 added to the display list
Final!!!
3

Если я правильно понял, функции _onEvt будут вызываться ровно столько раз, сколько мы раз мы будем что-либо добавлять addChild-ом к this-у, что, наверное, неправильно...

Замена на:
this.addEventListener(Event.ADDED_TO_STAGE, addedHandler);
вроде бы решает эту проблему...
Просьба меня поправить, если я не прав...

etc
08.11.2007, 13:39
Я бы рекомендовал ознакомиться, что такое высплывающее событие и как устроена display модель в AS3. Потом вопросы должны отпасть сами собой.