2009-06-24 4 views
6

Ich arbeite an einer Webseite, die Dojo verwendet und eine Nummer (6 in meinem Testfall, aber in der Regel variabel) von Projekt-Widgets darauf hat. Ich Aufruf dojo.addOnLoad (init), und in meiner Funktion init() habe ich diese Zeilen:Warum kann ich keine Schleife in Javascript rollen?

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);}); 

und Ereignisse ändern für mein Projekt-Widgets die makeMatch Funktion richtig aufrufen. Aber wenn ich sie mit einer Schleife ersetzen:

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

gleiche makeMatch() Funktion, gleiche init() Aufruf, gleiche alles andere - nur meine Anrufe Aufrollen in eine Schleife - die makeMatch Funktion nie aufgerufen wird; Die Objekte sind nicht verkabelt.

Was ist los und wie kann ich es beheben? Ich habe versucht, dojo.query, aber sein Verhalten ist das gleiche wie die for-Schleife Fall.

Antwort

11

dies ist ein häufiges Problem wenn es um Schließungen geht. versuchen Sie dies:

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

Ausgezeichnet; Danke; das funktioniert perfekt. Ich denke, ich werde lange brauchen, um die Schließungen zu verstehen. –

+6

bekommen Sie ein Buch mit dem Titel "Javascript die guten Teile" und Sie werden Verschlüsse verstehen, unter anderem. – mkoryak

+0

Danke; Ich werde danach suchen. –

8

i ist eine lokale Variable innerhalb der for-Schleife. Wenn die onChange Funktion aufgerufen wird, haben alle sechs Funktionen i eine Referenz, die 6 ist

Es ist das gleiche Problem wie #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(); 
} 

die alle Drucke 10