【问题标题】:Angular's change detections mechanism lets me down角度变化检测机制让我失望
【发布时间】:2019-02-04 19:29:50
【问题描述】:

到现在为止,我已经为一个非常奇怪的问题战斗了一个多小时:

<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 大师,也不太了解变更检测机制。求救。

【问题讨论】:

  • 是有问题的组件使用ChangeDetectionStrategy.OnPush吗?
  • 在第二种情况下,您在哪里称呼console.log?您可能想在现有的之后添加另一个 tap 并记录标志和签名用户值的状态
  • @Jota.Toledo,不,实际上我都试过了,希望能轻松解决问题。两种方法都行不通。
  • 布尔标志正确更新。除非点击按钮,否则 UI 不会重新呈现;然后它会立即更改并显示正确的数据,而无需任何额外的工作(没有 HTTP,没有可观察的,什么都没有)。
  • 如果您将回调代码从tap 移动到subscribe,行为是否会发生任何变化?

标签: angular angular-material angular-ng-if angular-changedetection


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2021-06-17
    • 2021-08-07
    • 2018-10-24
    • 1970-01-01
    • 2018-06-23
    • 1970-01-01
    • 2018-05-07
    • 1970-01-01
    • 2017-12-03
    相关资源
    最近更新 更多