2010-01-19 50 views
2

我正在使用Google Maps API在地圖上繪製幾個點。然而,在下面的點擊事件功能,i始終設置爲4,即其價值迭代循環後:在子函數中訪問循環迭代?

// note these are actual addresses in the real page 
var addresses = new Array("addr 1", "addr 2", "addr 3", "addr 4"); 

for (var i = 0; i < addresses.length; i++) { 
    geocoder.getLatLng(addresses[i], function(point) { 
     if (point) { 
      var marker = new GMarker(point); 
      map.addOverlay(marker); 
      map.setCenter(point, 13); 

      GEvent.addListener(marker, "click", function() { 
       // here, i=4 
       marker.openInfoWindowHtml("Address: <b>" + addresses[i] + "</b>"); 
      }); 
     } 
    }); 
} 

所以當標記顯示它的使用addresses[4]這是不確定的。如何將i的正確值傳遞給函數?

+0

我用一點解釋更新了我的答案。當我提供我的答案時,我的意思是寫更多,但我不得不去想,最好至少提供一個解決方案。 – 2010-01-19 22:02:03

回答

1

你需要生成當前迭代過程的匿名函數,下面應該修復它:

// note these are actual addresses in the real page 
var addresses = new Array("addr 1", "addr 2", "addr 3", "addr 4"); 

for (var i = 0; i < addresses.length; i++) { 
    geocoder.getLatLng(addresses[i], function (current) { 
     return function(point) { 
      if (point) { 
       var marker = new GMarker(point); 
       map.addOverlay(marker); 
       map.setCenter(point, 13); 

       GEvent.addListener(marker, "click", function() { 
        // here, i=4 
        marker.openInfoWindowHtml("Address: <b>" + addresses[current] + "</b>"); 
       }); 
      } 
     } 
    }(i)); 
} 

乙//注意這些都是在現實頁面實際地址 VAR地址=新的Array(「地址1「,」addr 2「,」addr 3「,」addr 4「);

爲(VAR I = 0;我< addresses.length;我++){ geocoder.getLatLng(地址[I]中,函數(點){ 如果(點){ VAR標記=新的GMarker(點) ; map.addOverlay(標記); map.setCenter(點,13);

 GEvent.addListener(marker, "click", function() { 
      // here, i=4 
      marker.openInfoWindowHtml("Address: <b>" + addresses[i] + "</b>"); 
     }); 
    } 
}); 

}

進一步明確
的0 Google提供的方法使用ajax調用獲取特定地址的經緯度。由於這是一個異步調用,並且不是當前線程的一部分,因此需要一個回調函數,在完成ajax請求時調用該函數。這是您指定爲函數的第二個參數的匿名函數。
現在,在進行ajax請求的同時,您的代碼將繼續運行,每次循環遍歷數組時,都會增加i的值。當你的第一個Ajax調用返回時,循環已經增加到了地址數組(4)的長度,所以當你的回調函數運行時,你將在循環增加後檢索範圍內的變量i

隨着我寫此修復程序,要創建一個匿名函數,它接受一個參數 - current - 並返回與i變量與current變量取代了以往匿名函數。該函數在循環的下一次迭代之前立即被調用,其變量爲i,因爲它是第一個參數。這將創建一個閉包,在該函數被調用時,i的當前值將被存儲在current變量中。當我們稍後參考current變量時,我們得到的存儲值爲i

我不是很善於解釋這些事情,可能是因爲我對它的理解不如js神。更好地閱讀some more info on javascript closures

+0

謝謝,這工作得很好!但我不完全明白它是如何工作的。 「getLatLng」上的谷歌地圖回調函數現在如何通過「i」而不是它原本的做法? – DisgruntledGoat 2010-01-19 20:20:53

+0

我試圖盡我所能解釋它(我不擅長解釋閉包笑),我希望它能幫助你理解它。我還發布了一個鏈接,通過搜索javascript閉包可以找到最佳網站。 – 2010-01-19 22:01:05

-1

我不應該在那個循環中達到4。循環運行,只要我地址。長度(這是4),所以循環應該從i = 0運行到i = 3。

+0

'我'必須增加到4,以便它可以通過'我<地址。長度'測試。 – 2010-01-19 18:29:38

+0

謝謝,是的,我注意到,我發佈後。今天結束的選票。管理員,隨時刪除這個答案。 – 2010-01-19 18:30:50

+0

不,我會達到4.試試看。當'i'達到4時循環停止,但'i'達到4時停止。由於'i'被閉包捕獲,所以在'i'達到4之後循環體不被評估並不重要,'i '仍然會被賦值爲4. – slebetman 2010-01-19 18:31:22