[英]Angular firebase subscribe function called twice
我正在尝试使用 mapbox-gl 在地图中的标记上的弹出窗口上制作按钮。 这些按钮允许订阅/取消订阅一个地方。 但是当我点击它们时,我看到 subscribe 函数被调用了两次并导致结果错误。
这是下面的第三个函数。
loadPlaces() {
this.placeService.getAll().subscribe(
(places: Place[]) => {
this.places = places;
this.places.forEach((place: Place) => {
const popup = new mapboxgl.Popup({ offset: 25 })
.setDOMContent(this.setPopUpContent(place));
new mapboxgl.Marker({color: 'red'})
.setLngLat(place.coordinates)
.setPopup(popup)
.addTo(this.map);
});
}
);
}
setPopUpContent(place: Place) {
const popupContent = document.createElement('div');
const title = document.createElement('p');
title.innerText = place.name;
const button = document.createElement('button');
button.innerText = 'Subscribe';
this.setSubscribeButton(place, button);
popupContent.append(title, button);
return popupContent;
}
setSubscribeButton(place: Place, button: any) {
this.placeSubscriptionService.isSubscribed(this.authService.getCurrentUser().uid, place.id).subscribe(subscribed => {
console.log(subscribed);
if (!subscribed) {
button.innerHTML = 'Subscribe';
button.onclick = () => {
this.subscribe(place);
};
} else {
button.innerHTML = 'Unsubscribe';
button.onclick = () => {
this.unsubscribe(place);
};
}
});
}
subscribe(place: Place) {
const placeSubscription: any = {
userId: this.authService.getCurrentUser().uid,
placeId: place.id
};
this.placeSubscriptionService.create(placeSubscription);
}
unsubscribe(place) {
this.placeSubscriptionService.getSubscriptionId(this.authService.getCurrentUser().uid, place.id).subscribe(subscriptionId => {
this.placeSubscriptionService.delete(subscriptionId);
});
}
这里是服务中的代码,用于检查用户是否订阅了 firestore 上的位置:
isSubscribed(userId: string, placeId: string): Observable<boolean> {
return this.firestore.collection<PlaceSubscription>(this.collectionName, ref => ref
.where('userId', '==', userId)
.where('placeId', '==', placeId))
.snapshotChanges()
.pipe(map(placeSubscriptions => {
const placeSubscription = placeSubscriptions[0];
if (placeSubscription) {
return true;
} else {
return false;
}
}));
}
当我单击订阅该地点的按钮时显示函数 isSubscribed 的结果时,它返回两次“true”。 在点击按钮取消订阅一次后,当我重新订阅时,它返回两次真,最后一次假。 所以我不能再订阅这个地方,因为它直接进入真假。
有什么我做错了吗?
非常感谢您的宝贵时间。
编辑 :
let subscription: Subscription;
const popup = new mapboxgl.Popup({ offset: 25 })
.on('open', () => {
console.log('open');
subscription = this.placeSubscriptionService.isSubscribed(this.authService.getCurrentUser().uid, place.id)
.pipe(first()).subscribe(
subscribed => {
console.log(subscribed);
popup.setDOMContent(this.setPopUpContent(place, subscribed));
});
})
.on('close', () => {
if (subscription) {
subscription.unsubscribe();
}
});
setPopUpContent(place: Place, subscribed: boolean) {
const popupContent = document.createElement('div');
const title = document.createElement('p');
title.innerText = place.name;
const button = document.createElement('button');
button.innerText = 'Subscribe';
if (subscribed) {
button.innerText = 'Unsubscribe';
button.onclick = () => {
this.unsubscribe(place);
};
} else {
button.innerText = 'Subscribe';
button.onclick = () => {
this.subscribe(place);
};
}
popupContent.append(title, button);
return popupContent;
}
这里涉及的代码很多,(如果你能提供最少的可重现代码,人们可以更好地帮助你)
无论如何,我认为有问题的是,您永远不会取消订阅 observable 并且与您调用的loadPlaces
一样多,它会调用越来越多
一种解决方法是下面的代码,因为first()
导致您的订阅结束
this.placeService.getAll()
.pipe(
first()
)
.subscribe(
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.