模板中具有 authState 可观察延迟的模板渲染中的 Angularfire 条件逻辑

Angularfire conditional logic in template with authState observable delay in template rendering

您好,我正在使用@angular/fire 构建一个angular 应用程序。在 auth 服务中,我有一个 user observable,如果用户通过身份验证,它获取当前用户的值,如果用户未通过身份验证,则获取 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);
        }
      })
    )
  }

它位于服务的构造函数中,因此注入服务的所有组件都可以看到用户$ variable.Now 假设我有一个导航,它根据用户是否经过身份验证显示不同的按钮。

<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>

user$ observable 在开始时是空的,需要一些时间 来获取值,这意味着即使用户已登录,在模板中 "This is visible if user is NOT logged in" 也会在 observable 获取当前用户的值之前呈现几秒钟,然后切换到另一个 li 标签。有没有更好的方法来检查经过身份验证的用户以防止这种情况发生?请注意,我不能使用路由保护,因为我不想阻止整个页面,而只想阻止按钮和其他一些元素之间的一些条件逻辑。这是这个问题的重复问题:Angular 6 AngularFireAuth check if user is logged in before page rendered 我没有找到答案。 提前致谢

在授权服务中添加组件可以订阅的主题并等待一些响应

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
    })
}