javascript - 每当我导航到另一条路线并返回时,Firestore 数据都会重复

标签 javascript angular google-cloud-firestore angularfire2

所以我有一个问题,我真的卡住了。我有一个使用 firestore 作为后端的 Angular 应用程序。我有一个从 firestore 检索数据的服务,但是当我在我的主页中显示它们时。当我导航到另一个页面并返回数据时,数据将被复制(只是在 View 中而不是在 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() 时,您都会为集合的更改注册一个新的观察者。由于您永远不会删除此观察者,因此您第二次构造 EvenmentService 时,它将注册第二个观察者。

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

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

关于javascript - 每当我导航到另一条路线并返回时,Firestore 数据都会重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51516092/

相关文章:

javascript - Facebook - JavaScript SDK - 如何自动请求许可

javascript - 即使 regExp 匹配,Angular 模板驱动表单的字段也被视为无效

html - 如何使功能成为指令,我必须在其他组件中使用它

swift - 将 Firebase Firestore 时间戳转换为日期(Swift)?

firebase - 在Firebase中的嵌套集合中查询文档值

javascript - Meteorjs实现无限滚动,先显示最新数据

javascript - 追加到 div 一次

javascript - indexedDB 中的 IN 运算符等价

angular - 如何设置 ngx-intl-tel-input 的初始值

flutter - 如何从 Streambuilder 订购项目