AngularFire 不会触发更改检测

Posted

技术标签:

【中文标题】AngularFire 不会触发更改检测【英文标题】:AngularFire doesn't trigger change detection 【发布时间】: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 值到达那里。 【参考方案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()


【讨论】:

不,很遗憾,这不是问题所在。当我使用构造函数时,行为不会改变。也就是说,错误仍然存​​在。不过还是谢谢。

以上是关于AngularFire 不会触发更改检测的主要内容,如果未能解决你的问题,请参考以下文章

v-model 不会检测到由 jQuery 触发事件所做的更改

TeamCity 不会触发自动构建

动态更改复选框不会触发 onChange?

如何在更改事件上检测CKEditor源模式

按下后退时 EditText 不会触发更改

按下后退时,EditText不会触发更改