【问题标题】:AngularFire doesn't trigger change detectionAngularFire 不会触发更改检测
【发布时间】:2020-05-16 01:46:24
【问题描述】:

我正在使用 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();
  }
}

然后,我将其注入我的HomeComponent 并订阅了isAuthenticated 方法返回的Observable

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

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

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

但是,如果我在 subscribe 之外调用 setTimeout(在此测试中延迟 10 秒),则组件将在这 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)
  }
}

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

【问题讨论】:

  • this.isLoggedIn.next(user !== null);你想通过这个达到什么目的?
  • 我无法回答这种现象,但您可以使用 ChangeDetectorRef .detectChanges() angular.io/api/core/ChangeDetectorRef#detectChanges 强制更新
  • 嗨,@varundhariyal。我将next 值发送给订阅者,在本例中为truefalse。这显然不是问题,因为 true 值到达那里。

标签: javascript angular rxjs firebase-authentication angularfire2


【解决方案1】:

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

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

}

【讨论】:

  • 不,很遗憾,这不是问题所在。当我使用构造函数时,行为不会改变。也就是说,错误仍然存​​在。不过还是谢谢。
猜你喜欢
  • 2017-06-19
  • 1970-01-01
  • 2019-05-07
  • 2021-09-02
  • 1970-01-01
  • 2018-08-03
  • 1970-01-01
  • 1970-01-01
  • 2019-04-21
相关资源
最近更新 更多