我添加了一个解析程序,以便在用户登录后从Cloud Firestore获取用户信息。但是,解析程序尚未完成,并且未呈现视图。
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
import {
AngularFirestore,
AngularFirestoreCollection,
AngularFirestoreDocument
} from 'angularfire2/firestore';
import {AngularFireAuth} from 'angularfire2/auth';
import { map } from 'rxjs/operators';
@Injectable()
export class LoginUserResolve implements Resolve<any> {
usersCollection: AngularFirestoreCollection<any>;
users: any;
userDoc: AngularFirestoreDocument<any>;
constructor(public afs: AngularFirestore, public afAuth: AngularFireAuth) {
this.usersCollection = this.afs.collection('users');
}
resolve(route: ActivatedRouteSnapshot) {
const email = this.afAuth.auth.currentUser.email;
console.log('Email: ', email);
return this.afs.collection('users', ref => ref.where('email', '==', email)).snapshotChanges().pipe(
map(actions => actions.map(proj => {
const data: any = proj.payload.doc.data();
data.id = proj.payload.doc.id;
return data;
})));
}
}
在控制台日志中,我看到正在记录用户的电子邮件,此后我没有看到该组件的任何日志。
答案 0 :(得分:0)
这是我的解决方法,我在Firestore返回后添加了可观察到的Firestore的缓存列表。并在下一个resolve调用中作为promise返回。尽管我确实认为应该由Firebase团队解决。
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { first } from 'rxjs/operators';
import { CurrencyApiService, ICurrency } from '../services/currency-api.service';
@Injectable()
export class CurrencyResolver implements Resolve<ICurrency[]> {
private list: ICurrency[] = [];
constructor(
private service: CurrencyApiService
) {}
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): any {
if (this.list.length > 0) {
return new Promise(resolve => resolve(this.list));
} else {
const doc = this.service.filteredCurrencies.pipe(first()).toPromise();
return doc.then(data => {
this.list = data;
return data;
});
}
}
}
答案 1 :(得分:0)
@Morilla Thaisa 几乎回答了评论中的问题。
不过,我想我会想出一个例子来说明它的样子。我自己在我的项目中使用它,并且效果很好。尽管如此,我认为 AngularFire 团队可以改进返回的对象,但这不取决于我,可能有使用 RxJS 运算符的解决方法,但我不确定。
路由模块
{
path: "about",
component: AboutComponent,
resolve: {
about: AboutResolver
}
},
服务
getAll<T>(c: string): Observable<QuerySnapshot<T>> {
this.increaseRequestsMade();
return this.firestore.collection<T>(c).get();
}
解析器
export class AboutResolver implements Resolve<QuerySnapshot<About>> {
constructor(private aboutService: AboutService) {}
resolve(
_route: ActivatedRouteSnapshot,
_state: RouterStateSnapshot
): Observable<QuerySnapshot<About>> | QuerySnapshot<About> {
return this.aboutService.getAll<About>();
}
}
组件
constructor(private route: ActivatedRoute) {}
ngOnInit(): void {
const aboutArray: About[] = this.route.snapshot.data.about.docs.map(d => d.data())
}
答案 2 :(得分:0)
我实际上在解析器中解决了所有问题。
通过提供在初始 Observable
本身发送其第一个值时完成的 Observable
。
因此,我没有返回数据,而是返回将发出值的 observable。
为了确保至少发出 1 个值,我使用了 delayWhen
运算符。
触发 delayWhen 后,我确保使用 take(1)
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Observable<Company>> {
return of(this._companyService.company$).pipe(
delayWhen(_ => this._companyService.company$.pipe(take(1))),
);
}
注意:CompanyService.company$
是一个 ReplaySubject<Company>(1)
。或者,您可以确保pipe(shareReplay(1))