2010-05-13 17 views
6

Prima domanda loop su StackOverflow :) Spero non voglio mettere in imbarazzo me stesso ...javascript problema portata quando la funzione lambda fa riferimento a una variabile nel racchiude

Ho una funzione javascript che carica un elenco degli album e poi si crea una voce di elenco per ogni album. L'elemento della lista dovrebbe essere cliccabile, quindi chiamo jQuery's click() con una funzione che fa roba. Lo faccio in un ciclo. Il mio problema è che tutti gli elementi sembrano avere la stessa funzione di clic, anche se provo a crearne uno nuovo che faccia cose diverse in ogni iterazione. Un'altra possibilità è che la variabile di iterazione sia globale in qualche modo e la funzione si riferisca ad essa. Codice sotto. debug() è solo un incapsulamento di console.debug() di Firebug.

function processAlbumList(data, c) { 
for (var album in data) { 
    var newAlbum = $('<li class="albumLoader">' + data[album].title + '</li>').clone(); 
    var clickAlbum = function() { 
    debug("contents: " + album); 
    }; 
    debug("Album: " + album + "/" + data[album].title); 
    $('.albumlist').append(newAlbum); 
    $(newAlbum).click(clickAlbum); 
} 
} 

Ecco una trascrizione di ciò che viene stampato quando la funzione di cui sopra viene eseguito, dopo che sono alcune linee di debug causati da me cliccando su oggetti diversi. Stampa sempre "10", che è l'ultimo valore che prende la variabile dell'album (ci sono 10 album).

Album: 0/Live on radio.electro-music.com 
Album: 1/Doodles 
Album: 2/Misc Stuff 
Album: 3/Drawer Collection 
Album: 4/Misc Electronic Stuff 
Album: 5/Odds & Ends 
Album: 6/Tumbler 
Album: 7/Bakelit 32 
Album: 8/Film 
Album: 9/Bakelit 
Album: 10/Slow Zoom/Atomic Heart 
contents: 10 
contents: 10 
contents: 10 
contents: 10 
contents: 10 

Tutte le idee? Guidandomi sul muro, questo è. :)

/Stefan

+2

See: http://stackoverflow.com/questions/1734749/ http://stackoverflow.com/questions/643542/ http://stackoverflow.com/questions/1582634/ http://stackoverflow.com/questions/1331769/ http://stackoverflow.com/questions/1552941/ http://stackoverflow.com/questions/750486/ http://stackoverflow.com/questions/933343/ http://stackoverflow.com/questions/1579978/ http://stackoverflow.com/questions/14139 16/ – CMS

+0

@CMS - wow, li raccogli? – harpo

+1

@harpo, sì, mi sono stancato di rispondere alla stessa domanda più e più volte ... :) – CMS

risposta

8

È necessario introdurre un altro campo di applicazione, come ad esempio in questo modo:

var clickAlbum = (function (a) { 
    return function() { 
     debug("contents: " + a) 
    }; 
})(album); 
+0

Meraviglioso! Molte grazie. Ho avuto la sensazione che questa fosse una di quelle stupide cose da principianti, ma stavo impazzendo ... –

0

Il album variabile nella funzione interna è una chiusura, ma il suo valore non è vincolata quando ogni la funzione è dichiarata. Ciò significa che ogni volta attraverso il loop, la chiusura dello album verrà modificata sul valore che ha in quel loop. C'è una spiegazione più dettagliata here

Come suggeriscono Sean (e l'articolo), è possibile risolvere questo problema modificando l'ambito della variabile.

+0

Il suggerimento di Yep Sean ha fatto funzionare tutto. In realtà stavo provando a cambiare l'ambito assegnando roba a una variabile locale nella funzione (e una miriade di altri pazzi tentativi), ma ora lo so meglio. Grazie per il link - Vado a dare un'occhiata. –

+0

Prego. Poiché la causa principale è abbastanza avanzata, potrebbe essere utile leggere il testo per ottenere una comprensione più profonda ... –

Problemi correlati