-----------------------------------

Acquista i software ArcGIS tramite Studio A&T srl, rivenditore autorizzato dei prodotti Esri.

I migliori software GIS, il miglior supporto tecnico!

I migliori software GIS, il miglior supporto tecnico!
Azienda operante nel settore GIS dal 2001, specializzata nell’utilizzo della tecnologia ArcGIS e aderente ai programmi Esri Italia Business Network ed Esri Partner Network

-----------------------------------



sabato 15 maggio 2010

Connections in un loop

Una situazione frequente quando sviluppiamo in javascript è l'impostazione di connection in un loop.
Supponiamo di avere una serie di elementi ( nell'esempio qui riportato dei div ) e voler loggare un valore quando passiamo sopra ad ognuno.

In prima battuta scriveremmo un codice del tipo:

 <html>
  
      <head>
  
           <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  
           <title>Test</title>
  
           <script type="text/javascript" src="http://o.aolcdn.com/dojo/1.4/dojo/dojo.xd.js"></script> 
  
           <script>
  
                dojo.addOnLoad(function( ) {
  
                     for (var i=1; i < 6; i++) {
  
                      var foo = dojo.byId("div"+i);
  
                      var handle = dojo.connect(foo, "onmouseover", function(evt) {
  
                                    console.log(i);
  
                        dojo.disconnect(handle);
  
                               });
  
                     }
  
                })
  
           </script>
  
      </head>
  
      <body>
  
           <div id="div1" style ="background-color:#EEEE00;">Div1</div>
  
           <div id="div2" style ="background-color:#FF0000;">Div2</div>
  
           <div id="div3" style ="background-color:#4466FF;">Div3</div>
  
           <div id="div4" style ="background-color:#F2921F;">Div4</div>
  
           <div id="div5" style ="background-color:#444444;">Div5</div>
  
      </body>
  
 </html>  


Il risultato però non è quello voluto. Innanzitutto viene sempre loggato il valore 6 mentre, ad eccezione del div5, il disconnect non viene rispettato.

Se ci pensiamo su un attimo, questo ha senso perchè la closure fornita dalla funzione anonima passata al dojo.connect non risolve la variabile i finchè non viene eseguita.

Per risolvere il problema intrappoliamo lo scope della variabile all'interno della funzione cosicchè, quando più tardi faremo riferimento, verrà risolto il valore precedentemente trattenuto.
In sostanza occorre inserire il corpo del loop in una funzione anonima che viene eseguita inline. Poichè la funzione anonima fornisce una closure di tutto quello che è contenuto, possiamo intrappolare con una variabile (current) il valore i. Inoltre risolviamo pure il problema dell'handle perchè anche per questo c'è la closure della funzione anonima.

 for (var i=1; i < 6; i++) {
  
   (function(){
  
    var current= i;
  
    var foo = dojo.byId("div"+i);
  
    var handle = dojo.connect(foo, "onmouseover", function(evt) {
  
        console.log(current);
  
        dojo.disconnect(handle);
  
       });
  
    })();
  
 }  

Nessun commento: