简体   繁体   English

嵌套闭包中无法识别循环中的变量

[英]A variable in a loop is not recognized in a nested closure

I have a JSON with some locations to show on a Google map with markers and info window. 我有一个带有某些位置的JSON,可在带有标记和信息窗口的Google地图上显示。

With a simple loop I can create the markers on the map (there are a lot of examples for putting many markers on a single map), but I have an extra level of difficulty: since I have physical addresses in the JSON, I have to geocode them first, translating into coordinates. 通过一个简单的循环,我可以在地图上创建标记(有很多将多个标记放置在单个地图上的示例),但是我还有一个额外的难度:因为我在JSON中有物理地址,所以我必须首先对它们进行地理编码,然后转换为坐标。

Anyway, I got working this too: for each loop, every JSON item is translated in its coordinates and a marker is added 无论如何,我也可以这样做:对于每个循环,每个JSON项都在其坐标中转换,并添加一个标记

But here comes the problem: in the geocode callback I can't access my current JSON item (I need it to build my info window)... It always returns the last JSON item, so it's unuseful 但是问题来了:在地址解析回调中,我无法访问我当前的JSON项(我需要它来构建我的信息窗口)...它总是返回最后一个JSON项,因此它是无用的

Here is a working snippet: 这是一个工作片段:

 var locations = [{"name":"Le Ginestre","address":"Via G. Marconi, Tremestieri Etneo"},{"name":"Le Zagare","address":"Via Manzoni, San Giovanni La Punta"},{"name":"Katan\è","address":"Via Quasimodo 1, Gravina di Catania"}]; function initMap(){ if (locations.length > 0){ var i; var map; var location; var geocoder; var position; var marker; var bounds = new google.maps.LatLngBounds(); var mapOptions = { mapTypeId: 'roadmap' }; map = new google.maps.Map(document.getElementById("map"), mapOptions); var infoWindow = new google.maps.InfoWindow(); for(i = 0; i < locations.length; i++){ location = locations[i]; geocoder = new google.maps.Geocoder(); geocoder.geocode({ 'address': location.address }, function(results, status){ console.log(location); // THIS RETURNS ALWAYS THE LAST JSON ITEM if (status === 'OK') { position = results[0].geometry.location; bounds.extend(position); map.fitBounds(bounds); marker = new google.maps.Marker({ position: position, map: map }); google.maps.event.addListener(marker, 'click', (function(marker) { return function() { // AND OF COURSE THIS SHOWS THE WRONG ADDRESS infoWindow.setContent(location.address); infoWindow.open(map, marker); } })(marker)); } }); } google.maps.event.addListenerOnce(map, 'bounds_changed', function() { this.setCenter(bounds.getCenter()); }); } } 
 #map { width:100%; height:300px; } 
 <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA222wozVyNudm3i0A2Tr_Vlmh_RipQ284&callback=initMap" async defer></script> <div id="map"></div> 

As you see, the console.log(location); // THIS RETURNS ALWAYS THE LAST JSON ITEM 如您所见, console.log(location); // THIS RETURNS ALWAYS THE LAST JSON ITEM console.log(location); // THIS RETURNS ALWAYS THE LAST JSON ITEM line is self explained, and the info window that opens on markers' click has always the same address console.log(location); // THIS RETURNS ALWAYS THE LAST JSON ITEM解释console.log(location); // THIS RETURNS ALWAYS THE LAST JSON ITEM行,并且在单击标记时打开的信息窗口始终具有相同的地址

I read some StackOverflow post (ie JavaScript closure inside loops – simple practical example ) but though the problem is similar I did not understood a lot... 我读了一些StackOverflow帖子( 例如,循环内的JavaScript闭合–简单的实际示例 ),但是尽管问题相似,但我还是不太了解...

Please any help? 请任何帮助? Thanks 谢谢

Ok, I searched better and I found the answer, thanks to the following articles: 好的,由于以下文章,我搜索得更好,找到了答案:

https://decembersoft.com/posts/understanding-javascript-closures-in-for-loops/ http://www.teknically-speaking.com/2013/01/closures-in-loops-javascript-gotchas.html https://decembersoft.com/posts/understanding-javascript-closures-in-for-loops/ http://www.teknically-speaking.com/2013/01/closures-in-loops-javascript-gotchas.html

Here is a working example: 这是一个工作示例:

 var locations = [{"name":"Le Ginestre","address":"Via G. Marconi, Tremestieri Etneo"},{"name":"Le Zagare","address":"Via Manzoni, San Giovanni La Punta"},{"name":"Katan\è","address":"Via Quasimodo 1, Gravina di Catania"}]; function initMap(){ if (locations.length > 0){ var i, map, position, marker, location, geocoder; var bounds = new google.maps.LatLngBounds(); var mapOptions = { mapTypeId: 'roadmap' }; map = new google.maps.Map(document.getElementById("map"), mapOptions); var infoWindow = new google.maps.InfoWindow(); for(i = 0; i < locations.length; i++){ location = locations[i]; // put geocoder stuff in a closure (function(item){ var name = '<b>' + item.name + '</b>'; var address = item.address; geocoder = new google.maps.Geocoder(); return geocoder.geocode({ 'address': address }, function(results, status){ if (status === 'OK') { position = results[0].geometry.location; bounds.extend(position); map.fitBounds(bounds); marker = new google.maps.Marker({ position: position, map: map }); google.maps.event.addListener(marker, 'click', (function(marker) { return function() { infoWindow.setContent(name + '<br>' + address); infoWindow.open(map, marker); } })(marker)); } }); })(location); } google.maps.event.addListenerOnce(map, 'bounds_changed', function() { this.setCenter(bounds.getCenter()); }); } } 
 #map { width:100%; height:300px; } 
 <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA222wozVyNudm3i0A2Tr_Vlmh_RipQ284&callback=initMap" async defer></script> <div id="map"></div> 

Hope this can be useful for people trying to work on Google Maps 希望这对尝试使用Google Maps的人们有用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM