AngularFire 不会触发更改检测

Dig*_*tuz 5 javascript rxjs firebase-authentication angularfire2 angular

我正在使用 AngularFire 和 Angular 8 来构建一个应用程序,但我有一个愚蠢的问题(我认为这实际上很愚蠢)。

我构建了一个简单的服务来包装AngularFireAuth

import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { User } from 'firebase';
import { Subject } from 'rxjs';
import { MessageService } from 'primeng/api';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  private user: Subject<User> = new Subject();
  private isLoggedIn: Subject<boolean> = new Subject();

  constructor(private afAuth: AngularFireAuth, private messageService: MessageService) {
    this.afAuth.auth.onAuthStateChanged(user => {
      this.user.next(user);
      this.isLoggedIn.next(user !== null);
    });
  }

  isAuthenticated() {
    return this.isLoggedIn.asObservable();
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,我将它注入到我的HomeComponent并订阅ObservableisAuthenticated方法返回的:

import { Component, OnInit } from "@angular/core"
import { AuthService } from '../auth/auth.service';

@Component({
  selector: 'app-homepage',
  styleUrls: ['./homepage.component.scss'],
  templateUrl: './homepage.component.html'
})
export class HomepageComponent implements OnInit {
  isAuthenticated: boolean = false;

  constructor(private authService: AuthService) { }

  ngOnInit() {
    this.authService.isAuthenticated().subscribe((isAuth) => {
      this.isAuthenticated = isAuth;
      console.log(`User is authenticated? ${this.isAuthenticated}`);
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,当subscribe调用传递给该方法的箭头函数时,不会执行重新渲染。但是,该console.log调用确实在 DevTools显示“用户已通过身份验证?true”。

我做过的其他一些测试:如果我setTimeout从传递给 的箭头函数内部调用subscribe,结果是一样的。无需重新渲染,DevTools 上的消息显示“用户已通过身份验证?真”。

但是,如果我调用setTimeout(在此测试中延迟 10 秒)外subscribe,组件将在这 10 秒后重新呈现:

import { Component, OnInit } from "@angular/core"
import { AuthService } from '../auth/auth.service';

@Component({
  selector: 'app-homepage',
  styleUrls: ['./homepage.component.scss'],
  templateUrl: './homepage.component.html'
})
export class HomepageComponent implements OnInit {
  isAuthenticated: boolean = false;

  constructor(private authService: AuthService) { }

  ngOnInit() {
    this.authService.isAuthenticated().subscribe((isAuth) => {
      this.isAuthenticated = isAuth;
      console.log(`User is authenticated? ${this.isAuthenticated}`);
    });

    setTimeout(() => {
      this.isAuthenticated = true;
      console.log(`User is authenticated? ${this.isAuthenticated}`);
    }, 10000)
  }
}
Run Code Online (Sandbox Code Playgroud)

我在这里缺少什么?我误解了什么?

小智 0

这是因为在组件初始化之后,您正在调用身份验证,在构造函数中调用它,它可以工作

import { Component, OnInit } from "@angular/core"
import { AuthService } from '../auth/auth.service';

@Component({
  selector: 'app-homepage',
  styleUrls: ['./homepage.component.scss'],
  templateUrl: './homepage.component.html'
})
export class HomepageComponent implements OnInit {
  isAuthenticated: boolean = false;

   constructor(private authService: AuthService) {
     this.authService.isAuthenticated().subscribe((isAuth) => {
      this.isAuthenticated = isAuth;
      console.log(`User is authenticated? ${this.isAuthenticated}`);
    });
    }

  ngOnInit(){}

}
Run Code Online (Sandbox Code Playgroud)