当服务发出更改时,组件模板变量不会更新(角度)

Jak*_*ers 1 javascript asynchronous observable rxjs angular

我有一个服务:

@Injectable({ providedIn: 'root' })
export class AuthenticationService {
  signInChange: Subject<boolean> = new Subject<boolean>();
  isSignedIn: boolean;

  constructor() {
    this.isSignedIn = false;
  }

  signInChange: Subject<boolean> = new Subject<boolean>();
  isSignedIn: boolean;

  login() {
    this.auth2.signIn()
      .then(user => {
        this.isSignedIn = true;
        this.signInChange.next(this.isSignedIn)
      })
      .catch(error => {
        console.log("Error signing in")
      })
  }

  logout() {
    this.auth2.signOut()
      .then(user => {
        this.isSignedIn = false;
        this.signInChange.next(this.isSignedIn)
      })
      .catch(error => {
        console.log("Error signing out")
      })
  }

Run Code Online (Sandbox Code Playgroud)

和一个组件:

export class HomeComponent implements OnInit {
  signInSubscription: Subscription;
  isSignedIn: any;

  constructor(private authService: AuthenticationService) {
    this.isSignedIn = authService.isSignedIn;
    this.signInSubscription = authService.signInChange.subscribe(value => {
      console.log("status changed to: " + value)
      this.isSignedIn = value
    })
  }

  checkValues() {
    console.log("Component says: " + this.isSignedIn);
    console.log("Auth says: " + this.authService.isSignedIn)
  }
Run Code Online (Sandbox Code Playgroud)

这是 HTML:

<div id = "login-test">
  <div class="g-signin2"></div>
  <button (click)="signIn()">Sign in</button>
  <button (click)="signOut()">Sign out</button>
  <button (click)="checkValues()">Check values</button>
  <p>{{this.isSignedIn}}</p>
</div>
Run Code Online (Sandbox Code Playgroud)

因此,可观察的工作按预期工作(例如,当登录状态更改时,会记录正确的状态),但在模板本身上,当观察到更改时,变量不会更新。

这是我不明白的地方:

  1. 当我单击“检查值”按钮时,输出始终正确。每次服务中有更新时,都会正确设置 isSignedIn 属性。但模板本身不会更新。

  2. 如果我设置一个按钮仅切换值 {{this.isSignedIn}},则模板会实时更新。如果更改来自可观察的内容,为什么它不会实时更新?!?

Mic*_*l D 5

isSignedIn因为in 中的变量HomeComponent在其构造函数中分配了一次,并且从未重新分配。您正走在正确的道路上,在服务中设置可观察的内容。当您需要组件中的最新值时,仅使用可观察的值,不要直接使用服务中的布尔标志。

在组件中执行以下操作。将分配移至订阅内,并避免直接使用服务中的布尔标志。

import { Component, ngOnInit, ChangeDetectorRef } from '@angular/core';

export class HomeComponent implements OnInit {
  signInSubscription: Subscription;
  isSignedIn: any;

  constructor(private authService: AuthenticationService, private changeDetectorRef: ChangeDetectorRef) {
    this.isSignedIn = authService.isSignedIn;
    this.signInSubscription = authService.signInChange.subscribe(value => {
      console.log("status changed to: " + value)
      this.isSignedIn = value;
      this.changeDetectorRef.detectChanges();
    })
  }

  checkValues() {
    console.log("Component says: " + this.isSignedIn);
    console.log("Auth says: " + this.authService.isSignedIn)
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑- 包含ChangeDetectorRef