В ActionScript 3, как я могу передать текущее значение массива в цикле слушателю событий - PullRequest
1 голос
/ 11 ноября 2009

Пример кода:

var gospels : Array = ["john", "mark", "matthew", "paul"];

for each (var book : String in gospels)
{
  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
  });
}

Как я могу заставить прослушиватель событий использовать значение массива в цикле при вызове функции прослушивателя событий? То есть когда я вызываю trace внутри функции прослушивателя событий, как я могу получить ее для вывода "john", "mark", "matthew" и "paul"?

Ответы [ 4 ]

4 голосов
/ 11 ноября 2009
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));
}
2 голосов
/ 11 ноября 2009

Я думаю, что более элегантный способ - написать суперкласс URLLoader, например:

class MyURLLoader extends URLLoader {
  public var book:String;

  function MyURLLoader(aBook:String){
    book = aBook;
    super();
  }
}

А затем используйте этот класс в вашем цикле, например:

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. В настоящее время я не за компьютером с флеш-памятью, поэтому у меня не было возможности проверить код.

1 голос
/ 11 ноября 2009

Вариант ответа Майкла Брюера-Дэвиса, но здесь используется Array.forEach и таким образом вводится новая переменная book для каждой итерации:

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); 
  });
});
0 голосов
/ 12 ноября 2009

Вот самый быстрый и лучший структурированный способ сделать это (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);
    }
}
...