Данные Firestore дублируются всякий раз, когда я перехожу к другому маршруту и ​​возвращаюсь

Так что у меня проблема, и я действительно застрял. У меня есть приложение 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>
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
200
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Каждый раз, когда вы вызываете this.eventsCollection.snapshotChanges(), вы регистрируете нового наблюдателя для изменений в коллекции. Поскольку вы никогда не удаляете этого наблюдателя, при втором построении EvenmentService он зарегистрирует второго наблюдателя.

Чтобы предотвратить это, вам нужно будет либо отстранить наблюдателя, когда служба выходит за пределы области видимости, либо вам нужно будет отслеживать, подключен ли наблюдатель уже при создании новой службы.

Какой из них лучше всего зависит от типа объекта: для синглтонов вы обычно хотите определить, зарегистрировали ли вы наблюдателя, поскольку они могут поддерживать состояние. Для объектов, жизненный цикл которых связан с экранами / представлениями вашего приложения, вы обычно хотите отсоединить наблюдателей в событии жизненного цикла вашей структуры, которое срабатывает при исчезновении экрана / представления.

спасибо за ваш ответ, это очень полезно, но не могли бы вы сказать мне, как я могу проверить, зарегистрировал ли я наблюдателя?

brahim belkhiria 26.07.2018 11:57

Вам нужно будет следить за этим самостоятельно, удерживая где-нибудь дескриптор наблюдателя. В обычном SDK JavaScript вы делаете это, вызывая ref.off(handleOfObserver) или ref.off() (что удаляет всех наблюдателей из этой ссылки). Я не очень хорошо сформулирован в AngularFire2, но мне кажется, что здесь нужен unsubscribe.

Frank van Puffelen 26.07.2018 15:13

Другие вопросы по теме