2009-06-24 9 views
6

Je travaille sur une page web qui utilise dojo et qui contient un nombre (6 dans mon cas de test mais variable en général) de widgets de projet. J'invoque dojo.addOnLoad (init), et dans ma fonction init() J'ai ces lignes:Pourquoi je ne peux pas lancer une boucle en Javascript?

dojo.connect(dijit.byId("project" + 0).InputNode, "onChange", function() {makeMatch(0);}); 
dojo.connect(dijit.byId("project" + 1).InputNode, "onChange", function() {makeMatch(1);}); 
dojo.connect(dijit.byId("project" + 2).InputNode, "onChange", function() {makeMatch(2);}); 
dojo.connect(dijit.byId("project" + 3).InputNode, "onChange", function() {makeMatch(3);}); 
dojo.connect(dijit.byId("project" + 4).InputNode, "onChange", function() {makeMatch(4);}); 
dojo.connect(dijit.byId("project" + 5).InputNode, "onChange", function() {makeMatch(5);}); 

et changer les événements pour mon projet widget droit invoquer la fonction makeMatch. Mais si je les remplacer par une boucle:

for (var i = 0; i < 6; i++) 
    dojo.connect(dijit.byId("project" + i).InputNode, "onChange", function() {makeMatch(i);}); 

même fonction makeMatch(), même init() invocation, même tout le reste - juste rouler mes appels en une boucle - la fonction makeMatch est jamais appelée; les objets ne sont pas câblés.

Que se passe-t-il et comment le réparer? J'ai essayé d'utiliser dojo.query, mais son comportement est le même que celui de la boucle for.

Répondre

11

c'est un problème commun lorsqu'il s'agit de fermetures. essayez ceci:

for (var i = 0; i < 6; i++) { 
    (function(i){ 
     dojo.connect(dijit.byId("project" + i).InputNode, "onChange", function() {makeMatch(i);}); 
    }(i)); 
} 
+0

Excellent; Je vous remercie; cela fonctionne parfaitement. Je pense qu'il me faudra beaucoup de temps pour comprendre les fermetures. –

+6

obtenir un livre appelé "javascript les bonnes parties" et vous comprendrez les fermetures, entre autres choses. – mkoryak

+0

Merci; Je vais le chercher. –

8

i est une variable locale à l'intérieur de la boucle for. Lorsque la fonction onChange est appelée, toutes les 6 fonctions ont une référence à i, qui est 6.

Il est le même problème que #4 on Jon Skeet's C# Brainteaser's page

List<Printer> printers = new List<Printer>(); 
for (int i=0; i < 10; i++) 
{ 
    printers.Add(delegate { Console.WriteLine(i); }); 
} 

foreach (Printer printer in printers) 
{ 
    printer(); 
} 

qui imprime tous les 10 de