Angular的变化检测机制让我失望

时间:2019-02-04 19:29:51

标签: angular angular-material ngif angular-changedetection

我到现在为止战斗了一个多小时,遇到了一个很奇怪的问题:

<mat-toolbar>
  <mat-toolbar-row>
    <ng-container *ngIf="!isSignedIn; else elseTemplate">
      <button mat-button [matMenuTriggerFor]="signInOptions">
        <i class="fas fa-sign-in-alt"></i>
      </button>
      <mat-menu #signInOptions="matMenu">
        <button mat-menu-item>
          <app-google-auth></app-google-auth>
        </button>
      </mat-menu>
    </ng-container>
    <ng-template #elseTemplate>
      <button mat-button [matMenuTriggerFor]="userOptions">
        <i class="fas fa-user"></i>
        {{ signedInUser.displayName }}
      </button>
      <mat-menu #userOptions="matMenu">
        <button mat-menu-item (click)="signOut()">
          Sign Out <i class="fas fa-sign-in-alt"></i>
        </button>
      </mat-menu>
    </ng-template>
  </mat-toolbar-row>
</mat-toolbar>

...以及上述视图背后的代码:

ngOnInit(): void {
    const authStateChangedSubject = new BehaviorSubject<firebase.User>(null);
    this.angularFireAuth.auth.onAuthStateChanged(
      next => authStateChangedSubject.next(next),
      error => authStateChangedSubject.error(error),
      () => authStateChangedSubject.complete());
    authStateChangedSubject.pipe(
      tap(
        firebaseUser => {
          if (firebaseUser) {
            this.isSignedIn = true;
            this.signedInUser = firebaseUser;
          } else {
            this.isSignedIn = false;
          }
        }))
      .subscribe();
  }

用例1,有效的一个:用户尚未登录;然后他或她会执行google-auth程序(具有Firebase提供的弹出机制)和 ng-if get是否会按预期立即更新

用例2,无效:用户登录并刷新页面之后-即使console.log报告isSignedIn如预期般变成true-除非有人按下按钮,否则不会发生视觉变化;仅在该按钮重新呈现为适当的ng-if选项之后。

我离Angular大师还很远,对变更检测机制也不了解。 SOS。

1 个答案:

答案 0 :(得分:0)

您是否正在使用Cookie / JWT来维护会话?刷新可能会破坏您的会话并清除isSignedIn值。

但是,请尝试使用双向绑定来确保组件和DOM保持同步:

<ng-container *ngIf="[(!isSignedIn)]; else elseTemplate">