簡體   English   中英

如何在分配給數組索引的對象上調用方法?

[英]How can I call a method on an object assigned to an array index?

為了在Google Map中創建標記的infowindows,我使用了一個數組在for循環中創建“一次性對象”。 但是,我的方法似乎不起作用。 單擊標記什么都不做,當我檢查控制台時,我收到此錯誤消息:

Uncaught TypeError: Cannot call method 'open' of undefined 

當我沒有將對象分配給數組索引時,單擊任何創建的標記只會打開最后一個信息窗口(這意味着當對象被覆蓋時,它會更新對前一個對象的所有引用)。

我怎么能繞過這個呢?

markers = []
infowindows = []
counter = 0
for location in exports.response.locations
    myLatlng = new google.maps.LatLng(location.latitude, location.longitude);
    markers[counter] = new google.maps.Marker(
        position: myLatlng
        map: map
        title: location.name
    )
    contentString = '<div id="info_content_' + location.id + '">' + '<h3>' + location.name + '</h3>' + '<ul>' + '<li>' + location.address + ', ' + location.city + '</li>' + '</ul>'
    infowindows[counter] = new google.maps.InfoWindow(content: contentString)

    google.maps.event.addListener markers[counter], "click", ->
        infowindows[counter].open(map, markers[counter])

    counter++

注意

問題區域是上面代碼中的第3行到最后一行。 infowindows[counter].open(map, markers[counter])

回答

事實上,每一個對這個問題的回復都幫助我找到了解決辦法,但是 - 為了記錄(以及之后准備好的人)我用foreach解決了這個問題:

markers = []
infowindows = []
exports.response.locations.forEach (location) ->
    myLatlng = new google.maps.LatLng(location.latitude, location.longitude);
    markers[location.id] = new google.maps.Marker(
        position: myLatlng
        map: map
        title: location.name
    )
    contentString = '<div id="info_content_' + location.id + '">' + '<h3>' + location.name + '</h3>' + '<ul>' + '<li>' + location.address + ', ' + location.city + '</li>' + '</ul>'
    infowindows[location.id] = new google.maps.InfoWindow(content: contentString)

    google.maps.event.addListener markers[location.id], "click", ->
        infowindows[location.id].open(map, markers[location.id])

我認為您的問題是counter將不再具有有效索引:

for location in exports.response.locations

    google.maps.event.addListener markers[counter], "click", ->
        infowindows[counter].open(map, markers[counter])

    counter++

counter在onClick處理程序閉包中捕獲。

在onClick處理程序運行之前,它將超出邊界。

所有這些處理程序最終將使用相同的counter值。

addListener異步觸發代碼。 因此,當調用監聽器的回調函數時,計數器的值與聲明函數時的值不同。 要將變量凍結為聲明函數時的值,必須將它們放在閉包中。 完整的證明選項如下。 在循環中聲明currentCounter應該足夠了,但它可能有助於明確使用閉包。

markers = []
infowindows = []
counter = 0
for location in exports.response.locations
    myLatlng = new google.maps.LatLng(location.latitude, location.longitude);
    markers[counter] = new google.maps.Marker(
        position: myLatlng
        map: map
        title: location.name
    )
    contentString = '<div id="info_content_' + location.id + '">' + '<h3>' + location.name + '</h3>' + '<ul>' + '<li>' + location.address + ', ' + location.city + '</li>' + '</ul>'

    infowindows[counter] = new google.maps.InfoWindow(content: contentString)
    google.maps.event.addListener markers[counter], "click", (function(infowindows, markers, currentcounter) { 
        return function() {  infowindows[currentCounter].open(map, markers[currentCounter]) }
    })(infowindows, markers, counter)
    counter++    

請參閱循環內的JavaScript閉包 - 更簡單的實際示例以獲取更多實際示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM