angular - 我可以完成一个 Angular FireStore Observable 并确保它加载了所有文档吗?
问题描述
正如标题所说,我想知道我是否可以使用 FireStore 中的数据完成一个 Observable 并确保它加载了所有数据。
我有一个最多每周更新一次的数据库。我不需要实时更新我的网站。
在我使用 FireStore 之前,我可以在函数complete
部分调用一个函数,subscribe
但由于 FireStore Observable 永远不会完成,这不再有效。
我在网上发现我可以通过取消订阅来“完成” 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
方法中,您有一个 Observable tracksCollection.get()
,您将其转换为 Promise,并使用结果创建一个新的 Observable。这没有多大意义。
您可能想要执行以下操作:
return tracksCollection.get().pipe(
map(querySnapshot => querySnapshot.map((doc => doc.data()))
)
然后在ngOnDestroy
组件的生命周期挂钩中,您可以:
this.trackSubscription.unsubscribe()
推荐阅读
- r - Tidyr 单独返回错误“_tidyr_simplifyPieces”
- string - 在 Python 中的另一行上放置一块分割线?
- python - 如何使用 patch.PathPatch 为矩形指定颜色列表?
- typeerror - 带有枚举的 for 循环生成 TypeError:'int' 对象不可迭代,Python
- ruby-on-rails - 带有文本和子元素的 Assert_select
- excel - 在 Excel 中使用 VBA 引用收件箱以外的 Outlook 邮箱
- regex - JMeter,正则表达式提取器
- python - Selenium 测试不能与任何元素交互
- node.js - 无论输入如何,节点 POST req 都返回相同的值
- amazon-web-services - 针对 HTTP 请求的 AWS Cognito UserPool 身份验证