我正在尝试从我的资源文件夹中加载xml文件。
我写了这个函数:
public static function loadXML(i_fileURL:String):XML // i want to return the actual loaded xml here
{
var xml:XML;
var ldr:URLLoader = new URLLoader();
var request:URLRequest = new URLRequest(i_fileURL);
ldr.addEventListener(Event.COMPLETE, onXMLLoad);
ldr.load(request);
//how can i return the loaded xml?
}
public static function onXMLLoad(e:Event):void
{
var ldr:URLLoader = URLLoader(e.target);
var myxml:XML = new XML(ldr.data);
trace(myxml.toXMLString());
//how can i return myxml to loadXML function?
}
有不同的方法吗?
谢谢!
答案 0 :(得分:1)
您可以执行类似承诺或未来的操作,返回空XML,然后在调用返回时使用实际XML填充它。由于您使用的是Flex,因此您可以访问数据绑定,这应该允许这种方法正常工作。
请注意,您确实不应该使用静态方法,并且您的onXMLLoad成员没有理由被公开。以下是更新后的代码:
package service { public class XMLLoader { //note that the existence of this variable means that you need //to create a new instance of the Class each time you make a call. protected var future:XML; protected var _url:String; public function loadXML(url:String):XML { _url = url; var request:URLRequest = new URLRequest(url); var loader:URLLoader = new URLLoader(); loader.addEventListener(Event.Complete, onLoad); loader.addEventListener(IoErrorEvent.IO_Error, onFail); loader.addEventListener(SecurityErrorEvent.Security_Error, onFail); future = ; return future; } protected function onLoad(e:Event):void { var loader:URLLoader = e.currentTarget as URLLoader; var data:XML = loader.data as XML; if (data) { //you lose your original root node, because you want data //binding to fire on the future object you returned. future.setChildren(data.children()); } } protected function onFail(e:Event):void { //both Security and IOerrors have a text property, but they //can't both be cast to the same thing. trace('failed to load', _url, e[text]); } } }
使用此方法需要注意的一件事是,您需要在数据更新之前保留对实例的引用,否则可能在填充未来之前对其进行垃圾回收。因此,您可能最好遵循传统的方法,让您的实例调度一个自定义事件,该事件包含它正在检索的数据。如果您想要一个例子,请回复,我可以为您提供一个示例。
答案 1 :(得分:0)
loadXML
时,onXMLLoad
尚未到达。所以这种工作不可能异步返回。当然你可以等待函数进程while
循环使用,但这种方法并不好。因为要充分利用cpu资源,矫枉过正。你必须在onXMLLoad
函数中进行下一步处理。这是最合适的。或声明为全局的xml变量,并使用ENTER_FRAME
或TimerEvent
作为在xml不为空时继续操作的方法。
答案 2 :(得分:0)
由于URLLoader是异步的,因此创建静态加载器函数并不安全,因为在多次调用期间很容易混淆返回的数据。即使您尝试使用Event.OPEN
和URL向量来跟踪每个URL应该属于哪些已完成的数据,也可以按照先到先得的原则进行操作不可能持久对齐文件URL和返回的数据。
我建议您创建使用自定义XMLLoader
的{{1}}类的实例,该类将返回xml数据和关联的文件URL。以下代码未经测试,但除了可能的拼写错误之外,它应该按预期工作。
使用案例
XMLLoaderEvent
<强> XMLLoader.as 强>
var xmlLoader:XMLLoader = new XMLLoader();
xmlLoader.addEventListener(XMLLoaderEvent.COMPLETE, xmlLoadCompleteEventHandler);
xmlLoader.load("myXMLFile.xml");
function xmlLoadCompleteEventHandler(event:XMLLoaderEvent):void
{
xmlLoader.removeEventListener(XMLLoaderEvent.COMPLETE, xmlLoadCompleteEventHandler);
trace(event.type, event.fileURL, event.xml);
}
<强> XMLLoaderEvent.as 强>
package
{
//Imports
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
//Class
public class XMLLoader extends EventDispatcher
{
//Properties
private var loader:URLLoader;
private var fileURL:String;
//Constructor
public function XMLLoader():void
{
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, loadCompleteEventHandler);
}
//Load
public function load(fileURL:String):void
{
this.fileURL = fileURL;
loader.load(new URLRequest(fileURL));
}
//Load Complete Event Hanlder
private function loadCompleteEventHandler(event:Event):void
{
loader.removeEventListener(Event.COMPLETE, loadCompleteEventHandler);
dispatchEvent(new XMLLoaderEvent(XMLLoaderEvent.COMPLETE, fileURL, XML(loader.data)));
}
}
}