带有ng-template和async的ngIf会在Angular中短暂显示错误的值

时间:2018-07-15 23:12:46

标签: angular

我只想显示注销或登录/登录按钮,具体取决于从服务器获取的isAuthenticated值。

重新加载页面后用户登录后,我会简要地看到登录/注册,然后注销d true 然后是 false

我注意到,如果删除感叹号<p>{{!(isAuthenticated$ | async)}}</p>,此效果将消失。

那么将值从true转换为false的操作要花费很多时间,以至于看不到? 如果为什么要先对表达式求值然后再呈现结果,为什么我会看到true然后是false? 为什么<p>{{(isAuthenticated$ | async)}}</p>没有帮助?

[ngIfElse]="loading"

2 个答案:

答案 0 :(得分:0)

这与您的IF条件和从服务器获取请求的延迟有关。解释第一部分-

let c;
if(!c){alert('hi')}

如果您在浏览器控制台中尝试上述操作,则会向您显示警报,因为我们说IF对于c的不存在或FALSY值是正确的。现在回到您的情况,我想您可以轻松地与以上联系。您的observable不包含任何值,并且!运算符使您的条件为true,因此在IF标志正在从服务器获取值的同时,您会看到async的内容持续一段时间。

根据我的理解,您也有一个ELSE模板,您可以在组件中使用具有默认FALSE值的变量,并在ngIf中使用它。在组件的ngOnInit中,订阅Observable,并在订阅中根据您的业务逻辑更改此FLAG的值。有了这个位置,您将看到ELSE模板处于加载状态,直到您的订阅获得价值,而价值IF导致FALSE之后。 或者,您可以使用角度RESOLVERS

答案 1 :(得分:0)

解决方案:

让我感到困惑的是,我曾经在网站上导航的一些链接通常是<a href="">链接,它们会重新加载整个应用程序。我已将它们替换为具有routerLink属性的按钮,并且在不重新加载应用程序的情况下,常量显示错误值的问题就消失了。现在,仅在刷新应用程序后问题仍然存在。

但是在重写有关@Avij的代码后,即使页面刷新,一切也按计划进行。我在组件中使用简单变量(而不是异步变量),首先用默认值初始化它们,然后在ngOnInit中从订阅中为它们分配实际值。

现在看起来像这样:

HTML:

<ng-template [ngIf]="isLoggedOut">
    <button routerLink="/sign-up" id="sign-up-button" mat-stroked-button>sign-up</button>
    <button routerLink="/sign-in" mat-stroked-button>sign-in</button>
  </ng-template>

  <button class="likeALink" id="logOut" *ngIf="isLoggedIn" mat-stroked-button (click)="logOut()">log-out</button>

组件:

ngOnInit(): void {

// initialize with default/fake values
    this.isLoggedIn = false;
    this.isLoggedOut = false;

// initialize with true value once with a method isUserAuthenticated()
    this.authService.isUserAuthenticated().subscribe(
      (isAuthenticated) => {
        this.isLoggedIn = isAuthenticated;
        this.isLoggedOut = !isAuthenticated;
      }
    );

// subscribe to Subject<boolean> to change authentication state. The 
    Subject is triggered on Sign-In and LogOut

this.authService.isAuthenticated.subscribe(
      (isAuthenticated) => {
        this.isLoggedIn = isAuthenticated;
        this.isLoggedOut = !isAuthenticated;
      }
    );

 }

注销方法:

  logOut() {
this.authService.isAuthenticated.next(false);

}

登录方法:

signIn(){
this.authService.isAuthenticated.next(true);
}