每当我导航到另一条路线并且 return 时,Firestore 数据就会重复

Firestore data are duplicating whenever i a navigate to another route and return

所以我有一个问题,我真的卡住了。我有一个使用 firestore 作为后端的 angular 应用程序。我有一个从 firestore 检索数据的服务,但是当我在我的主页中显示它们时。当我导航到另一个页面并且 return 数据将被复制(只是在视图中而不是在 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);
    });
  }







}

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>

每当您调用 this.eventsCollection.snapshotChanges() 时,您都会为集合的更改注册一个新的观察者。因为你永远不会删除这个观察者,所以你第二次构造一个 EvenmentService 它将注册第二个观察者。

为防止这种情况,您需要在服务超出范围时 detach the observer,或者您需要在构建新服务时跟踪观察者是否已附加。

哪一个最好取决于对象的类型:对于单例,您通常想要检测您是否已经注册了观察者,因为它们可以保持状态。对于生命周期与应用程序的 screens/views 相关联的对象,您通常希望在 screen/view 消失时触发的框架生命周期事件中分离观察者。