Reputation: 6702
How can I reorganise the code below so the trace commands output i for each element in the photourls array and not just the last element? In a 6 element array, the trace(i);
line outputs 5,5,5,5,5,5 rather than 0,1,2,3,4,5.
for (var i in photourls) {
loaders[i] = new Loader();
var img:URLRequest = new URLRequest(photourls[i]);
loaders[i].load(img);
addChild (loaders[i]);
loaders[i].contentLoaderInfo.addEventListener(Event.COMPLETE, function(e){
trace(i);
trace(loaders[i]);
});
}
Thanks a lot
Upvotes: 0
Views: 482
Reputation: 81998
The problem is with this code here:
loaders[i].contentLoaderInfo.addEventListener(Event.COMPLETE, function(e){
trace(i);
trace(loaders[i]);
});
Because "i" will continue to alter throughout the course of the surrounding loop, only the final value of "i" will be used here. I suggest this change:
// place this outside of the loop.
function independantTrace( ...args:Array ):Function
{
return function( ...a:* ):void{trace( args.join( "\n" ) );}
}
loaders[i].contentLoaderInfo.addEventListener(Event.COMPLETE,
independantTrace(i,loaders[i]));
That will bind the function to values of i and loaders[ i ] at that moment in the loop instead of to the "i" variable.
Upvotes: 2
Reputation: 39456
// list of photo urls
var photourls:Array = [/* ??? */];
// vars
var vars:Array = [];
var count:uint = 0;
// loop vars
var info:Object;
var ldr:Loader;
var img:URLRequest;
// load images in list
var i:String;
for each(i in photourls)
{
ldr = new Loader();
img = new URLRequest(i);
/**
* DEFINE YOUR VARS IN THIS OBJECT
* -------------------------------
*/
info =
{
target: ldr.contentLoaderInfo,
url: i,
counter: ++count,
other: img
};
vars[vars.length] = info;
ldr.load(img);
addChild(ldr);
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, _complete);
}
// complete event
function _complete(e:Event):void
{
var t:LoaderInfo = LoaderInfo(e.target);
// find storage object
var object:Object;
for each(object in vars)
{
if(object.target == t) break;
}
// example trace of info
trace(object.url);
trace(object.counter);
t.removeEventListener(Event.COMPLETE, _complete);
}
The above is an extremely messy example, I'd create your own loader class that has its own variables that you want to track and set those variables when you create your loaders. I'll do an example.
Your MyLoader class:
package
{
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
public class MyLoader extends Loader
{
// vars
private var _url:String;
public var id:uint;
/**
* Loads an object
* @param url The URL to the object to load
*/
public function myLoad(url:String):void
{
var req:URLRequest = new URLRequest(url);
load(req);
contentLoaderInfo.addEventListener(Event.COMPLETE, _complete);
_url = url;
}
/**
* Load complete
*/
private function _complete(e:Event):void
{
contentLoaderInfo.removeEventListener(Event.COMPLETE, _complete);
trace(id, url);
}
/**
* Getters
*/
public function get url():String{ return _url; }
}
}
And then looping through your list and creating these:
var photourls:Array = [/* ??? */];
var ldr:MyLoader;
var id:uint = 0;
var i:String;
for each(i in photourls)
{
ldr = new MyLoader();
ldr.id = ++id;
ldr.myLoad(i);
addChild(ldr);
}
Upvotes: 2