2009-06-24 9 views
6

Estoy trabajando en una página web que utiliza dojo y tiene un número (6 en mi caso de prueba, pero variable en general) de los widgets del proyecto. Estoy invocando dojo.addOnLoad (init), y en función de mi init() tengo estas líneas:¿Por qué no puedo hacer un ciclo 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);}); 

y eventos de cambio para mi proyecto Widgets invocar adecuadamente la función makeMatch. Pero si los sustituye por un bucle:

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

misma makeMatch(), misma init (invocación), mismo todo lo demás - sólo rodar mis llamadas hasta en un bucle - la función makeMatch nunca es llamado; los objetos no están cableados

¿Qué está pasando y cómo lo soluciono? Intenté usar dojo.query, pero su comportamiento es el mismo que el del caso de bucle for.

Respuesta

11

este es un problema común cuando se trata de cierres. intente esto:

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

Excelente; gracias; esto funciona perfectamente Creo que me llevará mucho tiempo entender los cierres. –

+6

obtenga un libro llamado "javascript the good parts" y comprenderá los cierres, entre otras cosas. – mkoryak

+0

Gracias; Lo buscaré. –

8

i es una variable local dentro del ciclo for. Cuando la función onChange se llama, los 6 funciones tienen una referencia a i, que es 6.

Es el mismo problema 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(); 
} 

que imprime todo de 10

Cuestiones relacionadas