Angular 我可以完成一个角度FireStore Observable并确保它加载了所有文档吗?
正如标题所说,我想知道我是否可以用FireStore中的数据完成一个Observable,并确保它加载了所有数据 我有一个数据库,每周最多更新一次。我不需要实时更新我的网站 在使用FireStore之前,我可以调用Angular 我可以完成一个角度FireStore Observable并确保它加载了所有文档吗?,angular,firebase,google-cloud-firestore,Angular,Firebase,Google Cloud Firestore,正如标题所说,我想知道我是否可以用FireStore中的数据完成一个Observable,并确保它加载了所有数据 我有一个数据库,每周最多更新一次。我不需要实时更新我的网站 在使用FireStore之前,我可以调用subscribe函数的complete部分中的函数,但由于FireStore Observable从未完成,因此不再工作 我在网上发现,我可以通过取消订阅来“完成”可观察到的数据,但我可以确定它已加载所有数据吗 如果相关的话,这里是我的服务和一些调用该服务的代码。可能还剩下一些其他功
subscribe
函数的complete
部分中的函数,但由于FireStore Observable从未完成,因此不再工作
我在网上发现,我可以通过取消订阅来“完成”可观察到的数据,但我可以确定它已加载所有数据吗
如果相关的话,这里是我的服务和一些调用该服务的代码。可能还剩下一些其他功能的代码
服务
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { shareReplay, map } from 'rxjs/operators';
import { Track } from '../model/track';
import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/firestore'
const CACHE_SIZE = 1;
@Injectable({
providedIn: 'root'
})
export class TrackService {
constructor(private http: HttpClient, private afs: AngularFirestore) { }
private tracks:Observable<Track[]>;
getTracks(){
if (!this.tracks) {
this.tracks = this.requestTracks().pipe(
shareReplay(CACHE_SIZE)
);
}
return this.tracks;
}
private requestTracks() {
var tracksStorage: Track[] = [];
var tracksObservable: Observable<Track[]>;
var tracksCollection: AngularFirestoreCollection<Track>;
tracksCollection = this.afs.collection("Songs");
tracksCollection.get().toPromise().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
tracksStorage.push(doc.data() as Track);
})
});
tracksObservable = new Observable(observer => {
observer.next(tracksStorage);
})
return tracksObservable;
}
}
this.trackSubscription = this.trackService.getTracks()
.subscribe(
trackData =>
{
trackData.forEach(track => {
console.log("Track data:"); // this is also not called. But probably different problem.
console.log(track);
track.lyrics = track.lyrics.replace(/(\\n)/g, '\n');
});
this.tracks = trackData as Track[]
},
err => {
console.log("error in Track Component");
console.log(err);
},
() => {
console.log('Retrieving tracks completed'); // never called
this.loadWithParams();
}
)
在
requestTracks
方法中,您可以从tracksCollection.get()
中获得一个可观察对象,将其转换为承诺,并使用结果创建一个新的可观察对象。这没有多大意义
您可能希望执行以下操作:
return tracksCollection.get().pipe(
map(querySnapshot => querySnapshot.map((doc => doc.data()))
)
然后在组件的ngondestory
生命周期挂钩中,您可以:
this.trackSubscription.unsubscribe()
我从教程中复制了这个方法。我尝试了你的建议,但得到的错误是'QuerySnapshot'类型上不存在'map'。我可以这样写:
trackscolection.get().pipe(map(querySnapshot=>querySnapshot.docs.map(doc=>doc.data()as Track))
但是“map”中的代码没有执行。(我对角度测量还比较陌生,但仍然感觉不到自己掌握了观察的窍门)另外,我已经退订了Ngondestory,但这还不够早。我想在数据加载后尽快完成可观测数据,以便在加载数据时对数据应用过滤器。(我在屏幕上显示了部分数据)@WhiteFalcon此代码应该可以工作(在您的评论中使用map进行更改)。此外,无需取消订阅,因为get()
在请求后完成(与例如valueChanges()
相反)。