如何在不重新加载页面的情况下更新从 firestore 检索到的标记在我的地图上?
Posted
技术标签:
【中文标题】如何在不重新加载页面的情况下更新从 firestore 检索到的标记在我的地图上?【英文标题】:How can I update markers, retrieved from firestore, on my map without reloading the page? 【发布时间】:2020-03-23 21:28:53 【问题描述】:我正在检索存储在我的 firestore 集合中的标记,并希望实时查看更改,而无需重新加载页面即可查看我的更改。 我的原始方法涉及使用 get(),我需要从中重新加载才能看到我的更改
db.collection('Limuru').get().then((snapshot) =>
snapshot.forEach(function(child)
addMarker();
)
);
然后我使用 OnSnapshot() 而不是 get() 。
db.collection('Limuru').onSnapshot(function(snapshot)
snapshot.forEach(function(child)
addMarker();
)
);
数据是实时变化的,但行为很奇怪,因为每次发生变化时,都会添加更多标记,而不会被替换。 如何重组我的代码以使其按我想要的方式工作?我应该使用 AJAX 还是更改 OnSnapshot 方法的逻辑? 完整代码如下:
<script src="https://www.gstatic.com/firebasejs/7.2.3/firebase-app.js"></script>
<script defer src="https://www.gstatic.com/firebasejs/7.2.3/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.2.3/firebase-firestore.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/OverlappingMarkerSpiderfier/1.0.3/oms.min.js"></script>
<link rel="stylesheet" type="text/css" href="map.css">
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="navbar.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<nav class="navbar navbar-dark bg-primary fixed-top" role="navigation">
<a class="navbar-brand" href="#">Radio Africa</a>
<a class="navbar-brand" id="loggedin"></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="./admin-map.php">Maps <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="">Error reports </a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Locations
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="./stations.php">Nairobi</a>
<a class="dropdown-item" href="./limuru.php">Limuru</a>
<a class="dropdown-item" href="./machakos.php">Machakos</a>
</div>
</li>
</div>
</nav>
<div id="map"></div>
<!------ Include the above in your HEAD tag ---------->
<script>
firebase.initializeApp(
apiKey: "xxxxxxxxxxxxxxxxxxxx",
authDomain: "xxxxxxxxxxxxxx",
projectId: "xxxxxxxxxxxxxx",
);
const db = firebase.firestore();
db.settings(timestampsInSnapshots: true);
var map;
var marker;
var infowindow;
var green_icon = 'http://maps.google.com/mapfiles/ms/icons/green-dot.png' ;
var red_icon = 'http://maps.google.com/mapfiles/ms/icons/red-dot.png' ;
var isBouncing;
function initMap()
var options =
zoom: 9,
center: lat: -1.2921, lng: 36.8219
;
var map = new google.maps.Map(document.getElementById('map'),options);
var oms = new OverlappingMarkerSpiderfier(map,
markersWontMove: true,
markersWontHide: true,
basicFormatEvents: true,
keepSpiderfied: true,
circleFootSeparation : 50,
);
function addMarker(coords, content, animation)
var marker = new google.maps.Marker(
position: coords,
map: map,
icon: icon =
url : isBouncing ? red_icon : green_icon,
scaledSize: new google.maps.Size(40, 40), // scaled size
// origin: new google.maps.Point(0,0), // origin
// anchor: new google.maps.Point(0, 0) // anchor
,
// IF THERE'S AN ERROR, BOUNCE IT
animation: animation
);
var infoWindow = new google.maps.InfoWindow(
content: content
);
marker.addListener('spider_click', function()
map.panTo(this.getPosition());
infoWindow.open(map,marker);
);
oms.addMarker(marker);
db.collection('Limuru').onSnapshot(function(snapshot)
snapshot.forEach(function(child)
var name_loc = child.id;
var loc = child.data().marker;
var forward = child.data().ForwardPower;
var reflected = child.data().ReflectedPower;
var ups = child.data().UPSError;
var upsDesc = child.data().UPSDesc;
var trans = child.data().TransmitterError;
var transDesc = child.data().TransDesc;
var kplc = child.data().KPLC;
var kplcDesc = child.data().KPLCDesc;
var sat = child.data().SatelliteReceiver;
var satDesc = child.data().SatDesc;
if(ups === true && trans ===true && sat ===true && kplc ===true)
isBouncing = true;
addMarker(
lat: loc.latitude, lng: loc.longitude ,
'' +
'<div id="iw-container">' +
`<div class="iw-title"> $name_loc</div>` +
'<div class="iw-content">' +
"<br/>"
+ `<p> UPSError: $upsDesc </p>`
+ `<p> SatelliteReceiver: $satDesc </p>`
+ `<p> KPLC: $kplcDesc </p>`
+ `<p> TransmitterError: $transDesc </p>`
+ '</div>' +
'<div class="iw-bottom-gradient"></div>' +
'</div>'
,google.maps.Animation.BOUNCE
);
)
)
<script async defer
src="https://maps.googleapis.com/maps/api/js?language=en&key=xxxxxxxxxxxxx&callback=initMap">
</script>
【问题讨论】:
【参考方案1】:如果我正确理解您的问题,这是因为每次触发侦听器时,您都会收到Limuru
集合中的所有文档。
你基本上有两种选择:
选项 1:重新初始化标记列表
即删除所有这些并重新创建它们
选项 2:聆听实际变化
正如doc 中所述,您可以检测“查询快照之间查询结果的实际变化”。
例如,您只能处理添加,如下所示:
db.collection('Limuru').onSnapshot((querySnapshot) =>
querySnapshot.docChanges().forEach((change) =>
if (change.type === "added")
addMarker();
if (change.type === "removed")
//Remove marker
//https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/marker-remove
//https://developers.google.com/maps/documentation/javascript/markers#remove
//.....
);
//....
);
【讨论】:
这很有趣,我会尝试一下,看看它是否按预期工作。以上是关于如何在不重新加载页面的情况下更新从 firestore 检索到的标记在我的地图上?的主要内容,如果未能解决你的问题,请参考以下文章
我们如何在不重新加载页面的情况下使用 javascript/jQuery 更新 URL 或查询字符串?
如何在不重新加载页面的情况下刷新 div 和 mysql 代码