javascript - 每当我导航到另一条路线并返回时,Firestore 数据就会重复
问题描述
所以我有一个问题,我真的被困住了。我有一个使用 firestore 作为后端的 Angular 应用程序。我有一项从 Firestore 检索数据的服务,但是当我在主页中显示它们时。当我导航到另一个页面并返回数据时,数据将被复制(只是在视图中而不是在 firestore 中)。下面是我的 hom 组件和我的事件服务。
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit, OnDestroy {
auth: AuthenticationService;
user ;
events: Evenement[];
subscription: Subscription;
constructor(auth: AuthenticationService, private eventService: EvenmentService, private attendService: AttendingService, private router: Router) {
this.auth = auth ;
this.user = auth.user$.subscribe( (user) => {
this.user = user;
});
}
ngOnInit() {
this.subscription = this.eventService.getEvents().subscribe((res) => {
console.log('loaded');
this.events = res;
}, (error1 => console.log(error1)));
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
}
这是活动服务
@Injectable()
export class EvenmentService implements OnInit {
eventsCollection: AngularFirestoreCollection<Evenement>;
events: Observable<Evenement[]>;
eventDoc: AngularFirestoreDocument<Evenement>;
ngOnInit(): void {
}
constructor(public afs: AngularFirestore, private router: Router) {
// this.events = this.afs.collection('events').valueChanges();
this.eventsCollection = this.afs.collection('events', ref => ref.orderBy('title', 'asc'));
this.events = this.eventsCollection.snapshotChanges().map(changes => {
return changes.map(a => {
const data = a.payload.doc.data() as Evenement;
data.id = a.payload.doc.id;
return data;
});
});
}
getEvents() {
return this.events;
}
addEvent(event: Evenement) {
this.eventsCollection.add(event).then(() => {
console.log('event added success');
}).catch((err) => {
console.log(err);
});
}
deleteEvent(event: Evenement) {
this.eventDoc = this.afs.doc(`events/${event.id}`);
this.eventDoc.valueChanges().subscribe(value => console.log(value));
this.eventDoc.delete().then(() => {
console.log('event deleted with succes');
}).catch((err) => {
console.log(err);
});
}
}
主页.html
<div *ngFor="let event of events" class="card border-dark mb-3" style="width: 318px;box-shadow: 1px 1px 1px 1px grey;">
<div class="card-header" style="background-color: white">Date : {{event.date.day}}-{{event.date.month}}-{{event.date.year}} | Available places : {{ event.nbreDePlace - event.reserved}}</div>
<div class="card-body text-dark">
<h5 class="card-title">{{event.title}}</h5>
<p class="card-text">{{event.description}}</p>
</div>
<div class="card-footer"style="background-color: white" >
<div *ngIf="already(event)" style="color: red;">you already subscribed to this event</div>
<button class="btn btn-default" (click)="attend(event)" [disabled]="!(event.reserved< event.nbreDePlace) || already(event)">Subscribe</button> </div>
<button class="btn " style="background-color: skyblue" (click)="detail(event)">view Details</button>
</div>
解决方案
每当您调用时this.eventsCollection.snapshotChanges()
,您都会注册一个新的观察者来更改集合。由于您从未删除此观察者,因此第二次构造 aEvenmentService
时,它将注册第二个观察者。
为了防止这种情况发生,您要么需要在服务超出范围时分离观察者,要么需要在构建新服务时跟踪观察者是否已经附加。
其中哪一个最好取决于对象的类型:对于单例,您通常希望检测您是否已经注册了观察者,因为它们可以保持状态。对于生命周期与应用程序的屏幕/视图相关联的对象,您通常希望在屏幕/视图消失时触发的框架的生命周期事件中分离观察者。
推荐阅读
- python - 如何在 for 循环中调用列表的不同部分?
- python - 如何优化我的 Tensorflow 代码(张量迭代)?
- firebase - 为特定的 Google 登录帐户设置自定义声明和基于角色的访问权限
- assembly - VPCMPB 的操作数
- r - 保持RMarkdown输出的html文件的复选框值
- javascript - 从数组中删除未经检查的值
- c# - WPF - 在 ListBox 中显示“TextChanged”事件导致新的 ObservableCollection
- aiohttp - Aiohttp 性能写入大 blob?
- azure-active-directory - MSAL - 使用 IneractionType.Redirect 时没有可用的令牌
- amazon-web-services - 如何在 Boto3 中使用 NextToken