我在Angular项目中使用angularfire2
以及Angular Material。
我认为让用户知道正在处理请求会很好。
不使用Firebase,我知道我可以使用Interceptors
来处理这类事情。但是使用Firebase,他们不再工作了。
所以我决定制作一个能够进行所有HTTP调用的服务,并使它成为拦截器。
我的问题是,当您创建请求时,创建的Observable永远不会结束。这意味着我可以显示进度状态,但从不隐藏它。
例如,我有这个方法,它返回集合的每个文档:
getCollection<T>(collection: string, query?: QueryFn): Observable<T[]> {
return (query ? this.db.collection<T>(collection, query) : this.db.collection<T>(collection)).valueChanges();
}
当应用程序提取集合时,如何显示进度条?
我经常这样做
getCollection<T>(collection: string, query?: QueryFn): Observable<T[]> {
this.loading = true;
return (query ? this.db.collection<T>(collection, query) : this.db.collection<T>(collection)).pipe(finalize(() => this.loading = false));
}
但valueChanges
阻止了这一点。
答案 0 :(得分:1)
如果您的观察结果永远不会完成,您可以使用点击操作符。当您的流发出没有副作用的新值时,此运算符用于执行操作:
getCollection<T>(collection: string, query?: QueryFn): Observable<T[]> {
this.loading = true;
return (query ? this.db.collection<T>(collection, query) : this.db.collection<T>(collection)).pipe(tap(() => this.loading = false));
}
编辑:如果您想模仿标准的API行为。您可以使用.take
运算符。
示例:
getCollection<T>(collection: string, query?: QueryFn): Observable<T[]> {
this.loading = true;
return this.db.collection<T>(collection, query)
.pipe(
take(1),
finalize(() => this.loading = false)
);
}
使用此take
运算符,您的observable将在首次数据发布后完成。但正如我在评论中所说,它打破了fireStore
的概念,因为如果您向集合添加其他项目,则需要再次调用getCollection
以获得新的Observable
。
return (query ? this.db.collection<T>(collection, query) : this.db.collection<T>(collection)).pipe(tap(() => this.loading = false));
到
return this.db.collection<T>(collection, query).pipe(tap(() => this.loading = false));