Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/420.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 每当我导航到另一条路线并返回时,Firestore数据都会重复_Javascript_Angular_Google Cloud Firestore_Angularfire2 - Fatal编程技术网

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

Javascript 每当我导航到另一条路线并返回时,Firestore数据都会重复,javascript,angular,google-cloud-firestore,angularfire2,Javascript,Angular,Google Cloud Firestore,Angularfire2,所以我有一个问题,我真的被卡住了。我有一个angular应用程序,它使用firestore作为后端。我有一个从firestore检索数据的服务,但是当我在我的主页中显示这些数据时。当我导航到另一个页面并返回时,数据将被复制(仅在视图中,而不是在firestore中)。下面是我的hom组件和我的活动服务 @Component({ selector: 'app-home', templateUrl: './home.component.html', styleUrls: ['./home

所以我有一个问题,我真的被卡住了。我有一个angular应用程序,它使用firestore作为后端。我有一个从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);
    });
  }







}
@Injectable()
导出类EvenmentService实现OnInit{
事件集合:AngularFirestoreCollection;
事件:可观察;
eventDoc:AngularFirestoreDocument;
ngOnInit():void{
}
构造器(公共afs:AngularFirestore,专用路由器:路由器){
//this.events=this.afs.collection('events').valueChanges();
this.eventscolection=this.afs.collection('events',ref=>ref.orderBy('title','asc'));
this.events=this.eventsCollection.snapshotChanges().map(更改=>{
返回changes.map(a=>{
const data=a.payload.doc.data()作为均衡;
data.id=a.payload.doc.id;
返回数据;
});
});
}
getEvents(){
返回此项。事件;
}
addEvent(事件:晚上){
this.events.collection.add(event).then(()=>{
console.log(“事件添加成功”);
}).catch((错误)=>{
控制台日志(err);
});
}
deleteEvent(事件:晚上){
this.eventDoc=this.afs.doc(`events/${event.id}`);
this.eventDoc.valueChanges().subscribe(值=>console.log(值));
this.eventDoc.delete()。然后(()=>{
console.log('成功删除事件');
}).catch((错误)=>{
控制台日志(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>

日期:{event.Date.day}-{event.Date.month}-{{event.Date.year}}}可用位置:{{event.nbreDePlace-event.reserved}
{{event.title}

{{event.description}

您已订阅此活动 订阅 查看详细信息
无论何时调用
this.eventsCollection.snapshotChanges()
都会注册一个新的观察者以查看集合的更改。由于您从未删除此观察者,因此第二次构建
EvenmentService
时,它将注册第二个观察者

为了防止出现这种情况,您需要在服务超出范围时进行跟踪,或者在构建新服务时需要跟踪观察者是否已连接


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

谢谢您的回答,这非常有帮助,但是您能告诉我如何检查我是否已经注册了观察者吗?您需要自己跟踪,将观察者的句柄保留在某个地方。在常规JavaScript SDK中,可以通过调用
ref.off(HandleOfOfOfOfOfOfOfOfOfOfOfOfOfServer)
ref.off()
(这将从该ref中删除所有观察者)来实现这一点。我在AngularFire2中的措辞不是很好,但似乎那里需要的是
取消订阅。