In ActionScript 3, how can I pass the current value of an array in a loop to an event listener
Code Example:
var gospels : Array = ["john", "mark", "matthew", "paul"];
for each (var book : String in gospels)
{
var loader : URLLoader = new URLLoader();
loader.load(new URLRequest("h开发者_JAVA百科ttp://example.com/" + name));
trace(book) // outputs current value of array
loader.addEventListener(Event.COMPLETE, function(e : Event) : void {
trace(book); // prints paul 4 times
});
}
How can I get the event listener to use the value of the array in the loop when the event listener's function was called? I.e. when I call trace inside the event listener's function, how can I get it to output "john"
, "mark"
, "matthew"
, and "paul"
?
var gospels:Array = ["john", "mark", "matthew", "paul"];
for each (var item:String in gospels)
{
(function(book:String){
var loader : URLLoader = new URLLoader();
loader.load(new URLRequest("http://example.com/" + name));
trace(book) // outputs current value of array
loader.addEventListener(Event.COMPLETE, function(e:Event):void {
trace(book); // prints paul 4 times
});
}(item));
}
I think a more elegant way is to write a superclass of URLLoader like:
class MyURLLoader extends URLLoader {
public var book:String;
function MyURLLoader(aBook:String){
book = aBook;
super();
}
}
And then use this class in your loop, like:
var gospels : Array = ["john", "mark", "matthew", "paul"];
for each (var book : String in gospels)
{
var loader : MyURLLoader = new MyURLLoader(book);
loader.load(new URLRequest("http://example.com/" + name));
trace(book) // outputs current value of array
loader.addEventListener(Event.COMPLETE, function(e : Event) : void {
var myUrlLoader:MyURLLoader = e.target as MyURLLoader;
trace (myUrlLoader.book);
});
}
P.S. I'm currently not behind a computer with flash so I did not have the opportunity to check the code.
A variant of Michael Brewer-Davis answer, but here using the Array.forEach and in that way introducing a new variable book
for each iteration:
var gospels : Array = ["john", "mark", "matthew", "paul"];
gospels.forEach(function (book: String, i: int, a: Array): void {
var loader : URLLoader = new URLLoader();
loader.load(new URLRequest("http://example.com/" + name));
trace(book) // outputs current value of array
loader.addEventListener(Event.COMPLETE, function(e : Event) : void {
trace(book);
});
});
Here's the fastest and best structured way to do it (imo):
var gospels:Array = ["john", "mark", "matthew", "paul"];
for(var book:String in gospels){ //For is faster than for each
var loader:URLLoader = new URLLoader();
//It's good practise to add the event listener before calling the function
loader.addEventListener(Event.COMPLETE, loaderComplete(book), false, 0, true);
loader.load(new URLRequest("http://example.com/" + name));
}
function loaderComplete(book:String):Function{
return function(event:Event):void{
event.target.removeEventListener(Event.COMPLETE, arguments.callee);
trace(book);
}
}
精彩评论