Так что у меня проблема, и я действительно застрял. У меня есть приложение angular, которое использует firestore в качестве бэкэнда. У меня есть служба, которая извлекает данные из хранилища огня, но когда я показываю их, например, на своей домашней странице. Когда я перехожу на другую страницу и возвращаюсь, данные будут дублироваться (только в представлении, а не в хранилище огня). ниже мой домашний компонент и моя служба мероприятий.
@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.info('loaded');
this.events = res;
}, (error1 => console.info(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.info('event added success');
}).catch((err) => {
console.info(err);
});
}
deleteEvent(event: Evenement) {
this.eventDoc = this.afs.doc(`events/${event.id}`);
this.eventDoc.valueChanges().subscribe(value => console.info(value));
this.eventDoc.delete().then(() => {
console.info('event deleted with succes');
}).catch((err) => {
console.info(err);
});
}
}
home.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>



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Каждый раз, когда вы вызываете this.eventsCollection.snapshotChanges(), вы регистрируете нового наблюдателя для изменений в коллекции. Поскольку вы никогда не удаляете этого наблюдателя, при втором построении EvenmentService он зарегистрирует второго наблюдателя.
Чтобы предотвратить это, вам нужно будет либо отстранить наблюдателя, когда служба выходит за пределы области видимости, либо вам нужно будет отслеживать, подключен ли наблюдатель уже при создании новой службы.
Какой из них лучше всего зависит от типа объекта: для синглтонов вы обычно хотите определить, зарегистрировали ли вы наблюдателя, поскольку они могут поддерживать состояние. Для объектов, жизненный цикл которых связан с экранами / представлениями вашего приложения, вы обычно хотите отсоединить наблюдателей в событии жизненного цикла вашей структуры, которое срабатывает при исчезновении экрана / представления.
Вам нужно будет следить за этим самостоятельно, удерживая где-нибудь дескриптор наблюдателя. В обычном SDK JavaScript вы делаете это, вызывая ref.off(handleOfObserver) или ref.off() (что удаляет всех наблюдателей из этой ссылки). Я не очень хорошо сформулирован в AngularFire2, но мне кажется, что здесь нужен unsubscribe.
спасибо за ваш ответ, это очень полезно, но не могли бы вы сказать мне, как я могу проверить, зарегистрировал ли я наблюдателя?