简体   繁体   English

*ngIf async pipe 问题

[英]*ngIf async pipe issue

I'm working on the Authentication of my Angular 11 project with AngularFire.我正在使用 AngularFire 对我的 Angular 11 项目进行身份验证。 I don't know why but I can't make *ngIf with the async pipe react to the auth state when refreshing the page.我不知道为什么,但是刷新页面时,我无法使用异步*ngIf对 auth state 做出反应。

Here is my code:这是我的代码:

AuthService:认证服务:

[...]
export class AuthService {
  public isAuth$ = new BehaviorSubject<boolean>(false);

  constructor(private angularFireAuth: AngularFireAuth,
              public router: Router) {

    this.angularFireAuth.onAuthStateChanged((user: any) => {
      if (user) {
                                                           // On reflesh
                                                           // when signed in
        console.log('signed in');                          //display signed in
        console.log('isAuth$:', this.isAuth$.getValue());  //display false

        this.isAuth$.next(true);                           

        console.log('isAuth$:', this.isAuth$.getValue()); //display true

      } else {
        console.log('signed out');
        this.isAuth$.next(false); 
      }
    });
  }

// Some Auth functions

}

Component.ts组件.ts

[...]
export class HeaderComponent implements OnInit {

  constructor(public authService: AuthService) {}

  public isAuth$ = new BehaviorSubject<boolean>(this.authService.isAuth$.getValue());

  ngOnInit(): void {
    this.isAuth$ = this.authService.isAuth$;
  }

}

Component html:组件 html:

<div>
   <a *ngIf="!(isAuth$ | async)">Sign in</a> 
   <a *ngIf="(isAuth$ | async)">Sign out</a>
<div>

What is appening is that when im signed in and refresh.正在出现的是,当我登录并刷新时。 Angular display the Signed Out state until i click on a field or a button... Angular 显示已注销的 state,直到我单击某个字段或按钮...

On refresh from signed in state the console log display:从登录 state 刷新后,控制台日志显示:

auth.service.ts:19 signed in
auth.service.ts:20 isAuth$: false
auth.service.ts:22 isAuth$: true

The value change on refresh so i was assuming the async pipe of *ngIf should react to those changes and display the good set of button right away.刷新时的值更改,因此我假设*ngIfasync pipe 应该对这些更改做出反应并立即显示一组好的按钮。 Hopping on your light to understand the issue.跳上你的灯来理解这个问题。

Should be like:应该是这样的:

export class HeaderComponent implements OnInit {

  constructor(public authService: AuthService) {}

  public isAuth$ = this.authService.isAuth$

  ngOnInit(): void {
    //this.isAuth$ = this.authService.isAuth$; --> remove this
  }
}

When you use getValue() on the BehaviorSubject , it will only get the value for that change detection cycle.当您在BehaviorSubject上使用getValue()时,它只会获取该更改检测周期的值。 You don't need to (actually shouldn't) reassign isAuth$ on ngOnInit您不需要(实际上不应该)在ngOnInit上重新分配isAuth$

Also html还有 html

<div>
   <a *ngIf="!(isAuth$ | async)">Sign in</a> 
   <a *ngIf="(isAuth$ | async)">Sign out</a> <!-- missing a $ here -->
<div>

You can also group the result like:您还可以对结果进行分组,例如:

<div *ngIf="isAuth$ | async as isAuth>
   <a *ngIf="!isAuth">Sign in</a> 
   <a *ngIf="isAuth">Sign out</a>
<div>

I find out the issue wasn't the pipe use or anything like that, but angular detection cycle like eko said.我发现问题不是 pipe 使用或类似的东西,而是像 eko 所说的 angular 检测周期。

public auth: boolean = false;

ngOnInit(): void {
  ngZone.run(() => {
    this.authService.auth$.subscribe((auth: boolean) => {
      this.auth = auth;
    });
  });
}

Component零件

<div>
   <a *ngIf="!isAuth">Sign in</a> 
   <a *ngIf="isAuth">Sign out</a>
<div>

Works perfectly fine.工作得很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM