Actionscript 3 - Как сохранить значение от события после удаления этого события - PullRequest
1 голос
/ 04 декабря 2011

Я устанавливаю значение для моего объекта xml (xml = new XML (e.currentTarget.data);) во время моей функции обработчика событий (функция выполняется после event.COMPLETE), и если я отслеживаю объект внутри своего событияобработчик функции показывает мои данные xml.

, но если я попытаюсь отследить его вне функции обработчика событий, он не покажет мое содержимое xml.Нет ли способа получить значение содержимого моего объекта xml для отображения в другой функции, но не в функции обработчика событий?

private var xml:XML; 

public function XMLLoader(xmlURL:String) 
{ 
    var xmlURLRequest:URLRequest = new URLRequest(xmlURL); 
    var xmlURLLoader:URLLoader  = new URLLoader(xmlURLRequest); 
    xmlURLLoader.addEventListener(Event.COMPLETE, xmlData); 
}

private function xmlData(e:Event):void 
{
    e.currentTarget.removeEventListener(Event.COMPLETE, xmlData); 
    xml = new XML(e.currentTarget.data); 
    dispatchEvent(new Event(Event.COMPLETE)); 
    trace(xml); 
} 

public function getXMLData():void 
{ 
     //I've find out that this shows null because this function is faster
     //what do i do? put an event.complete in every following function?
    trace(xml);
}

Спасибо.

Ответы [ 4 ]

1 голос
/ 05 декабря 2011

Я думаю, что вы вызываете getXMLData() сразу после XMLLoader(), в этот момент xml объект по-прежнему нулевой.Попробуйте вызвать getXMLData() внутри xmlData() функции, и вы увидите разницу.

0 голосов
/ 06 декабря 2011

// ПРИМЕЧАНИЕ: ИСПОЛЬЗУЙТЕ ЭТО, ЕСЛИ ВЫ ХОТИТЕ ПРЯМОГО ДОСТУПА К ФУНКЦИЯМ ЭТОГО «КЛАССА», БЕЗ ИСПОЛЬЗОВАНИЯ ЛЮБОГО ЛИСТЕНЕРА СОБЫТИЙ В КЛАССЕ, ПОЧЕМУ ЭТО УЖЕ ЕГО СЛУЧАЙНЫЙ СЛУШАТЕЛЬ НА КАЖДОЙ ФУНКЦИИ (ЭТО ПРИЧИНА ОДНА ФУНКЦИЯ ТОЛЬКО (getXata) )

private var xml: XML;

публичная функция XMLLoader (xmlURL: String) {

     var xmlURLRequest:URLRequest = new URLRequest(xmlURL); 
     var xmlURLLoader:URLLoader  = new URLLoader(xmlURLRequest); 
     xmlURLLoader.addEventListener(Event.COMPLETE, xmlData); 

}

приватная функция xmlData (e: Event): void {

     e.currentTarget.removeEventListener(Event.COMPLETE, xmlData); 
     xml = new XML(e.currentTarget.data); 
     dispatchEvent(new Event(Event.COMPLETE)); 
     trace("1");//this used to come second of getXMLData() but it's solved now
     trace(xml); 

}

публичная функция getXMLData (): void {

     //This function was coming first so if you don't want to use an event listener outside    
     //this class to wait for event.complete you can use it here to wait for it and access
     //the function directly without being afraid of the object being null:
     addEventListener(Event.COMPLETE, go)
     function go(e:Event){
          trace("2"); //now it ONLY comes AFTER the event.complete, no need for external                   listeners over this class. declare the class object and use getXMLData() directly cause it always comes second the event handler xmlData() :)
          trace(xml);
     }
}
0 голосов
/ 05 декабря 2011

измените метод трассировки, чтобы указать, загружен ли еще xml ...
вы столкнулись с состоянием гонки

private var _xmlLoaded:Boolean=false;// add this to see if the xml is loaded
private function xmlData(e:Event):void 
{
    e.currentTarget.removeEventListener(Event.COMPLETE, xmlData); 
    xml = new XML(e.currentTarget.data); 
    _xmlLoaded=true;
    dispatchEvent(new Event(Event.COMPLETE)); 
    trace(xml); 
} 
public function getXMLData():void 
{ 
    if (_xmlLoaded)
        trace(xml);
    else
        trace("not yet loaded");
}
0 голосов
/ 05 декабря 2011

Вы, вероятно, вызываете getXMLData () до того, как ваш URLLoader завершает работу, однако, в общем случае код, который вы выполняете, имеет плохую практику.Actionscript не имеет никаких блокировок, поэтому, когда вы создаете новый URLLoader с помощью URLRequest, он немедленно начинает операцию загрузки.Например, если ваш файл кэшируется, ваш прослушиватель Event.COMPLETE может никогда не сработать, так как вы присоединяете его после начала операции загрузки.

Ниже приведен идеальный процесс создания и загрузки данных:

var data:XML;
var urlLoader:URLLoader = new URLLoader();

urlLoader.addEventListener(Event.COMPLETE, urlLoader_completeHandler);
urlLoader.load(new URLRequest("path"));

private function urlLoader_completeHandler(event:Event):void
{
    data = new XML(urlLoader.data);
}

Если вы хотите применить это к вашему собственному классу XMLLoader, я включил "правильную" реализацию в AS3 ... однако довольно многословно.

import flash.net.URLLoader;
import flash.events.Event;

class XMLLoader extends URLLoader
{
    public function XMLLoader()
    {
        super();
        addEventListener(Event.COMPLETE, completeHandler);
    }

    private function completeHandler(event:Event):void
    {
        dispatchEvent(new XMLLoaderEvent(XMLLoaderEvent.COMPLETE, new XML(data)));
    }
}

class XMLLoaderEvent extends Event
{
    public static const COMPLETE:String = "xmlLoaderComplete";

    public var data:XML;

    public function XMLLoaderEvent(type:String, data:XML = null, bubbles:Boolean = false, cancelable:Boolean = false)
    {
        super(type, bubbles, cancelable);

        this.data = data;
    }

    override public function clone():Event
    {
        return new XMLLoaderEvent(type, data, bubbles, cancelable);
    }
}

Чтобы использоватьКласс XMLLoader:

var xmlLoader:XMLLoader = new XMLLoader();
xmlLoader.addEventListener(XMLLoaderEvent.COMPLETE, function(event:XMLLoaderEvent):void
{
    trace(event.data);
});

xmlLoader.load(new URLRequest("data.xml"));

Удачи!

...