How to get associated URLRequest from Event.COMPLETE fired by URLLoader
So let's say we want to load some XML -
var xmlURL:String = 'content.xml';
var xmlURLRequest:URLRequest = new URLRequest(xmlURL);
var xmlURLLoader:URLLoader = new URLLoader(xmlURLRequest);
xmlURLLoader.addEventListener(Event.COMPLETE, function(e:Event):void{
trace('loaded',xmlURL);
trace(XML(e.target.data));
});
If we need to know the source URL for that particular XML doc, we've got that variable to tell us, right? Now let's imagine that the xmlURL variable isn't around to help us - maybe we want to load 3 XML docs, named in sequence, and we want to use throwaway variables inside of a for-loop:
for(var i:uint = 3; i > 0; i--){
var xmlURLLoader:URLLoader = new URLLoader(new URLRequest('content'+i+'.xml'));
xmlURLLoader.addEventListener(Event.COMPLETE, function(e:Event):void{
trace(e.target.src); // I wish this worked...
trace(XML(e.target.data));
});
}
Suddenly it's not so easy, right?
I hate that you can't just say e.target.src or whateve开发者_高级运维r - is there a good way to associate URLLoaders with the URL they loaded data from? Am I missing something? It feels unintuitive to me.
for (var i:uint = 3; i > 0; i--) {
var src:URLRequest = new URLRequest('content'+i+'.xml');
var xmlURLLoader:URLLoader = new URLLoader(src);
xmlURLLoader.addEventListener(Event.COMPLETE, function(req:URLRequest):Function {
return function(e:Event):void {
trace(req); // Should work
// whatever you need to do
}
}(src));
}
You've gotta use the second function to wrap the request, otherwise all three event listeners will reference the last request.
sberry2A is on the right track. Robert Penner recently showed us that URLLoader is nothing but a tiny wrapper around the native URLStream, so rolling your own URLLoader is a reasonable idea.
This is how I roll:
public class URLLoader extends EventDispatcher{
private var _urlRequest:URLRequest; //the built-in URLLoader doesn't give you any access to the requested URL...
private var _stream:URLStream;
private var _dataFormat:String;// = "text"
private var _data:*;
private var _bytesLoaded:uint;// = 0
private var _bytesTotal:uint;// = 0
public function get request():URLRequest { return _urlRequest;}
public function get fileName():String { return _urlRequest.url.match(/(?:\\|\/)([^\\\/]*)$/)[1];}
public function get dataFormat():String { return _dataFormat;}
public function get data():* { return _data; }
public function get bytesLoaded():uint { return _bytesLoaded; }
public function get bytesTotal():uint { return _bytesTotal; }
public function URLLoader(request:URLRequest = null){
super();
_stream = new URLStream();
_stream.addEventListener(Event.OPEN, openHandler);
_stream.addEventListener(ProgressEvent.PROGRESS, progressHandler);
_stream.addEventListener(Event.COMPLETE, completeHandler);
_stream.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
_stream.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
_stream.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
if (request != null){
load(request);
};
}
public function load(request:URLRequest):void {
_urlRequest = request;
_stream.load(_urlRequest);
}
public function close():void{
_stream.close();
}
private function progressHandler(event:ProgressEvent):void {
_bytesLoaded = event.bytesLoaded;
_bytesTotal = event.bytesTotal;
dispatchEvent(event);
}
private function completeHandler(event:Event):void{
var bytes:ByteArray = new ByteArray();
_stream.readBytes(bytes);
switch (_dataFormat){
case "binary":
_data = bytes;
break;
case "variables":
if (bytes.length > 0){
_data = new URLVariables(bytes.toString());
break;
};
case "text":
default:
_data = bytes.toString();
break;
};
trace("URLLoader: (" + fileName + "): " + event.type);
dispatchEvent(event);
}
private function openHandler(event:Event):void {
trace("URLLoader: ("+fileName+"): " + event.type +" "+_urlRequest.url);
dispatchEvent(event);
}
private function securityErrorHandler(event:SecurityErrorEvent):void {
trace("URLLoader ("+fileName+"): " + event.type + " - " + event.text);
dispatchEvent(event);
}
private function httpStatusHandler(event:HTTPStatusEvent):void {
dispatchEvent(event);
}
private function ioErrorHandler(event:IOErrorEvent):void {
trace("URLLoader ("+fileName+"): " + event.type + " - " + event.text);
dispatchEvent(event);
}
}
Notice the request and fileName properties. To get the URLRequest from the COMPLETE-event handler, you simply do: var req:URLRequest = URLLoader(evtObj.target).request;
精彩评论