我正在尝试使用for循环在infowindow中使用Wikipedia AJAX数据生成Google Map标记。我认为有一个时间问题,但几个星期后我无法弄清楚如何解决它。当我将标识符硬编码到for循环中以替换i(例如2)时,代码工作得很好......但是当我使用i时,我会收到错误,说“无法读取未定义的属性[无论如何”。我已经玩过setTimeout和回调,但我似乎无法弄明白。
这是我的代码:
var map;
var marker;
var infowindow;
var wikiURL;
var i;
var text;
var venueInfo;
var markers = [];
var markerNames = [];
var wikiURLs = [];
var venueArray = [];
//The Model - Pro/Collegiate Stadiums in PGH, Pa.
var venues = [
{
name: "PNC Park",
lat: 40.446855,
lng: -80.0056666
},
{
name: "Heinz Field",
lat: 40.4466765,
lng: -80.01576
},
{
name: "PPG Paints Arena",
lat: 40.439593,
lng: -79.989338
},
{
name: "Highmark Stadium",
lat: 40.4362358,
lng: -80.00959209999999
},
{
name: "Peterson Events Center",
lat: 40.443828,
lng: -79.962283
}
];
//marker creator
function createMarker(){
for (i=0; i <= venues.length; i++){
wikiURL = 'http://en.wikipedia.org/w/api.php?action=opensearch&search=' +venues[i].name+ '&format=json&callback=wikiCallback';
wikiURLs.push(wikiURL);
$.ajax ({
url: wikiURL,
dataType: "jsonp",
success: function(data){
text = data[2];
venueInfo = text[0];
console.log(venueInfo);
marker = new google.maps.Marker({
position: {lat: venues[i].lat, lng: venues[i].lng},
map: map,
draggable: false,
content: '<h2>'+venues[i].name+'</h2><p>'+venueInfo+'</p>'
});
markerNames.push(venues[i].name);
markers.push(marker);
infowindow = new google.maps.InfoWindow({
content: this.content
});
marker.addListener('click', function(){
infowindow.setContent(this.content);
infowindow.open(map, this);
});
}
});
}
}
//Map Initializer
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 40.446855, lng: -80.0056666},
zoom: 14,
mapTypeId: 'satellite'
});
//viewmodel();
createMarker();
}
&#13;
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='css/bootstrap-theme.min.css'>
<link rel='stylesheet' href='css/main.css'>
</head>
<body>
<nav>
</nav>
<container>
<div id='map'>
</div>
</container>
<script type='text/javascript' src='js/jquery-3.2.1.min.js'></script>
<script type='text/javascript' src='js/knockout-3.4.2.js'></script>
<script type='text/javascript' async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA_WObUiYD7YpoYufR84re1LZHAJeAGXkY&v=3&callback=initMap">
</script>
<script type='text/javascript' src='js/app.js'></script>
</body>
&#13;
答案 0 :(得分:2)
正如@jeff carey所说,修复你的循环并将你的ajax代码移动到单独的函数
function doAjax(i){
wikiURL = 'http://en.wikipedia.org/w/api.php?action=opensearch&search=' +venues[i].name+ '&format=json&callback=wikiCallback';
wikiURLs.push(wikiURL);
$.ajax ({
url: wikiURL,
dataType: "jsonp",
success: function(data){
text = data[2];
venueInfo = text[0];
marker = new google.maps.Marker({
position: {lat: venues[i].lat, lng: venues[i].lng},
map: map,
draggable: false,
content: '<h2>'+venues[i].name+'</h2><p>'+venueInfo+'</p>'
});
markerNames.push(venues[i].name);
markers.push(marker);
infowindow = new google.maps.InfoWindow({
content: this.content
});
marker.addListener('click', function(){
infowindow.setContent(this.content);
infowindow.open(map, this);
});
}
});
}
function createMarker(){
for (i=0; i < venues.length; i++){
doAjax(i);
}
}
答案 1 :(得分:0)
在循环中调用异步函数会导致一个常见问题。解决问题的一种方法(当回调函数运行时,i
超过输入数组的末尾)是一个立即调用的函数表达式(IIFE),它保存i
变量的闭包,所以当执行回调函数时,它具有&#34;正确的&#34;值:
success: (function(i) {
return function(data) {
text = data[2];
venueInfo = text[0];
console.log(venueInfo);
marker = new google.maps.Marker({
position: {
lat: venues[i].lat,
lng: venues[i].lng
},
map: map,
draggable: false,
content: '<h2>' + venues[i].name + '</h2><p>' + venueInfo + '</p>'
});
markerNames.push(venues[i].name);
markers.push(marker);
infowindow = new google.maps.InfoWindow({
content: this.content
});
marker.addListener('click', function() {
infowindow.setContent(this.content);
infowindow.open(map, this);
});
}
}(i))
(正常工作)代码段
var map;
var marker;
var infowindow;
var wikiURL;
var i;
var text;
var venueInfo;
var markers = [];
var markerNames = [];
var wikiURLs = [];
var venueArray = [];
//The Model - Pro/Collegiate Stadiums in PGH, Pa.
var venues = [{
name: "PNC Park",
lat: 40.446855,
lng: -80.0056666
},
{
name: "Heinz Field",
lat: 40.4466765,
lng: -80.01576
},
{
name: "PPG Paints Arena",
lat: 40.439593,
lng: -79.989338
},
{
name: "Highmark Stadium",
lat: 40.4362358,
lng: -80.00959209999999
},
{
name: "Peterson Events Center",
lat: 40.443828,
lng: -79.962283
}
];
//marker creator
function createMarker() {
for (i = 0; i < venues.length; i++) {
wikiURL = 'https://en.wikipedia.org/w/api.php?action=opensearch&search=' + venues[i].name + '&format=json&callback=wikiCallback';
wikiURLs.push(wikiURL);
$.ajax({
url: wikiURL,
dataType: "jsonp",
success: (function(i) {
return function(data) {
text = data[2];
venueInfo = text[0];
console.log(venueInfo);
marker = new google.maps.Marker({
position: {
lat: venues[i].lat,
lng: venues[i].lng
},
map: map,
draggable: false,
content: '<h2>' + venues[i].name + '</h2><p>' + venueInfo + '</p>'
});
markerNames.push(venues[i].name);
markers.push(marker);
infowindow = new google.maps.InfoWindow({
content: this.content
});
marker.addListener('click', function() {
infowindow.setContent(this.content);
infowindow.open(map, this);
});
}
}(i))
});
}
}
//Map Initializer
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 40.446855,
lng: -80.0056666
},
zoom: 14,
mapTypeId: 'satellite'
});
//viewmodel();
createMarker();
}
&#13;
html,
body,
#map {
height: 100%;
width: 100%;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<container>
<div id='map'>
</div>
</container>
<script type='text/javascript' async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap">
</script>
&#13;