我尝试使用firebase和google maps API的组合在地图上创建交互式标记。
我可以生成标记,但我想找到一种方法来删除它们。
我生成一个地址列表,其中包含一个可以推送的按钮。如果按下该按钮,则通过将setMap设置为null来删除标记。
但是,在clearItem函数中引用我的标记时,它会给ems错误"不能引用未定义的setMap"
任何帮助?
我使用的数组如
var markerArray = [];
firebase.database().ref().on('value', function(snapshot)
{
var pointerLocations = document.getElementById("locations");
var databaseKeys = snapshot.val(); //Returns one object of many object attributes
var list="";
if(databaseKeys == null){
console.log("Error handled");
}
else{
for(i = 0 ; i < Object.keys(databaseKeys).length; i ++){
list += databaseKeys[Object.keys(databaseKeys)[i]].address + "<br>";
list += databaseKeys[Object.keys(databaseKeys)[i]].name + "<br>";
var keyString = Object.keys(databaseKeys)[i].toString();
list += "<button class = \"clrbtn\" id = \"clrbtn_"+i+"\" onclick = \"clearItem('"+keyString+"',"+i+")\">Delete Item</button>"
//Calls google map
codeAddress(databaseKeys[Object.keys(databaseKeys)[i]].address, map,i);
}
}
pointerLocations.innerHTML = list;
}
);
function codeAddress(address,mapGlobl,i) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == 'OK') {
// map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
markers.push(marker);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
function clearItem(databaseID,position){
firebase.database().ref(databaseID).remove();
markers[i].setMap(null);
}
编辑:回应评论
使用i变量来使用对象而不是数组
firebase.database().ref().on('value', function(snapshot)
{
var pointerLocations = document.getElementById("locations");
var databaseKeys = snapshot.val(); //Returns one object of many object attributes
var list="";
if(databaseKeys == null){
console.log("Error handled");
}
else{
for(i = 0 ; i < Object.keys(databaseKeys).length; i ++){
list += databaseKeys[Object.keys(databaseKeys)[i]].address + "<br>";
list += databaseKeys[Object.keys(databaseKeys)[i]].name + "<br>";
var keyString = Object.keys(databaseKeys)[i].toString();
list += "<button class = \"clrbtn\" id = \"clrbtn_"+i+"\" onclick = \"clearItem('"+keyString+"',"+i+")\">Delete Item</button>"
//Calls google map
codeAddress(databaseKeys[Object.keys(databaseKeys)[i]].address, databaseKeys[Object.keys(databaseKeys)[i]].name, map,i);
}
}
pointerLocations.innerHTML = list;
}
);
function codeAddress(address, name, mapGlobl,i) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == 'OK') {
// map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
latLongObj[i] = {lat : results[0].geometry.location.lat(), lng : results[0].geometry.location.lng(), add: address, name : name};
console.log("Placing Market at " + i);
markers['marker'+i] = marker;
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
function clearItem(databaseID,position){
console.log(markers);
console.log("Removing at position: "+ position);
firebase.database().ref(databaseID).remove();
markers['marker'+position].setMap(null);
delete markers['marker'+position];
console.log(markers);
}
答案 0 :(得分:1)
问题是geocoder.geocode()
函数是异步的。来自Google Maps JS文档:
访问地理编码服务是异步的,因为Google Maps API需要拨打外部服务器。因此,您需要传递一个回调方法,以便在请求完成时执行。
你的markers.push(marker);
正在回调函数中发生。因为它是异步的,所以不能保证何时/是否会被调用。 push()
函数将天真地使用下一个可用的数组索引将标记添加到数组中,但是您正在根据函数调用之间传递的i
值执行所有操作。如果Google Maps API出现任何问题,并且回调函数永远不会被调用,或者在延迟后被调用(例如由于网络延迟),那么事情可能会无序地添加到标记数组或者数组索引中存在间隙。
最简单的解决方案是将markers.push(marker);
更改为markers[i] = marker;
这可以保证将其添加到带有您期望的索引的markers数组中(并且它与i
值匹配那个<button>
元素。)