嗨,我正在用@ angular / fire构建一个角度应用程序。在auth服务中,我有一个用户可观察的用户,如果该用户已通过身份验证,则获取当前用户的值;如果该用户未通过身份验证,则获取null的值。
export class AuthService {
user$: Observable<User>;
constructor(private afAuth: AngularFireAuth, private afs:
AngularFirestore) {
this.user$ = this.afAuth.authState.pipe(
switchMap(user => {
if (user) {
return this.afs.doc<User>(`users/${user.uid}`).valueChanges();
} else {
return of(null);
}
})
)
}
它在服务的构造函数中,因此所有注入服务的组件都可以看到user $变量。现在,我有一个导航,它根据用户是否通过身份验证显示不同的按钮。
<ul>
<!-- user IS NOT logged in -->
<li *ngIf="!(authService.user$ | async)">
This is visible if user is NOT logged in
</li>
<!-- user IS logged in -->
<li *ngIf="authService.user$ | async" fxHide.xs>
This is visible if user IS logged in
</li>
</ul>
observable用户$在开始时为空,并且需要一些时间取值,这意味着即使用户已登录,模板中的“如果用户未登录也可见”。将在可观察对象获取当前用户的值之前渲染几秒钟,然后切换到另一个li标签。有没有更好的方法来检查经过身份验证的用户以防止这种情况?注意我不能使用路由保护,因为我不想阻塞整个页面,而只能阻塞按钮和某些其他元素之间的某些条件逻辑。这是与此重复的问题:Angular 6 AngularFireAuth check if user is logged in before page rendered,但我没有找到答案。 预先感谢
答案 0 :(得分:1)
在auth服务中,添加一个主题,组件可以订阅该主题并等待某些响应
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
@Injectable()
export class AuthService {
userAccessSubject = new Subject();
user$: Observable<User>;
constructor(private afAuth: AngularFireAuth, private afs:
AngularFirestore) {
this.afAuth.authState.pipe(
switchMap(user => {
if (user) {
this.userAccessSubject.next(this.afs.doc<User>(`users/${user.uid}`).valueChanges());
} else {
this.userAccessSubject.next(null);
}
})
)
}
getUserAccess() {
return this.userAccessSubject.asObservable();
}
}
然后在组件中,从订阅块获取userAccess
constructor() {
// Here add code to enable loader
this.authService.getUserAccess()
.subscribe(userAccessResponse => {
this.userAccess = userAccessResponse;
// Hide loader
})
}