Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 带有ng模板和async的ngIf在角度上短暂显示错误的值_Angular - Fatal编程技术网

Angular 带有ng模板和async的ngIf在角度上短暂显示错误的值

Angular 带有ng模板和async的ngIf在角度上短暂显示错误的值,angular,Angular,我只想根据从服务器获取的isAuthenticated值显示注销或登录/注册按钮 当用户在重新加载页面后登录时,我会短暂地看到登录/注册,然后注销{{{!(isAuthenticated$| async)}为true,然后为false 我注意到,如果我删除感叹号{(isAuthenticated$| async)},这种效果就会消失 那么将值从真值翻转为假值的操作花费的时间太长以至于肉眼可见? 如果要先对表达式求值,然后再呈现结果,为什么我会看到true和false呢? 为什么[ngIfElse

我只想根据从服务器获取的isAuthenticated值显示注销或登录/注册按钮

当用户在重新加载页面后登录时,我会短暂地看到登录/注册,然后注销
{{{!(isAuthenticated$| async)}

为true,然后为false

我注意到,如果我删除感叹号
{(isAuthenticated$| async)}

,这种效果就会消失

那么将值从真值翻转为假值的操作花费的时间太长以至于肉眼可见? 如果要先对表达式求值,然后再呈现结果,为什么我会看到true和false呢? 为什么
[ngIfElse]=“加载”
没有帮助

     <p>{{!(isAuthenticated$ | async)}}</p>
      <ng-template [ngIf]="!(isAuthenticated$ | async)" [ngIfElse]="loading">
        <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="isAuthenticated$ | async" mat-stroked-button (click)="logOut()">log-out</button>

      <ng-template #loading></ng-template>
{{!(isAuthenticated$| async)}

报名 登录 注销
这与从服务器获取请求时的IF条件和延迟有关。为解释第一部分—

let c;
if(!c){alert('hi')}
如果您在浏览器控制台中尝试上述操作,它将向您显示警报,因为对于
c
的不存在或错误值,我们说
If
为true。现在回到你的情况,我想你可以很容易地与上面的内容联系起来。您的可观察对象不包含任何值和
运算符使您的条件为真,因此在
async
标志从服务器获取值时,您可以在一段时间内看到
IF
的内容

根据我的理解,由于您还有一个
ELSE
模板,您可以在组件中使用带有默认
FALSE
值的变量,然后在
ngIf
中使用该变量。在组件的ngOnInit中,订阅可观察的,在订阅中,根据您的业务逻辑更改此标志的值。在这个位置上,您将看到ELSE模板一直处于加载状态,直到您的订阅获得值为止,如果结果为FALSE,则显示after值。
或者您可以使用角度解决方案:

<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);
}
同样让我感到困惑的是,我用来浏览网站的一些链接通常都是
链接,它们会重新加载整个应用程序。我已经用
routerLink
属性将它们替换为按钮,当应用程序没有重新加载时,常量显示错误值的问题消失了。现在,只有当你刷新应用程序时,问题才会出现

但是在重写了关于@Avij advice的代码之后,即使在页面刷新时,一切都按计划进行。我在组件中使用简单变量(非异步),首先用默认值初始化它们,然后在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);
}
}

登录方法:

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

我没有意识到未定义的
c
将被视为false,条件将得到满足。如果我在ngOnInit中初始化observable,不管我将在那里输入什么值,我最终都会得到错误的结果(例如:我用false预定义了我的observable-现在如果用户真的登录,它将显示登录/注册按钮,这是错误的,反之亦然)第二次之后,当实际值将被提取时,可观测值将被覆盖-我将看到有效结果-这将提供相同的视觉效果。我想在从服务器提取数据时,用空模板替换ng模板,并使用
[ngIfElse]=“loading”
。我想你没有理解我。你是如何被观察到的?我建议在组件中创建一个新变量,并将其保持为false,这样在加载时您将看到ELSE模板,当值出现时,相应地您的ngIf将工作。这意味着在ngOnInit和subscription中使用subscribe方法而不是async标志,将服务结果分配给您的变量(建议在上面创建),谢谢您的建议!我必须使用两个变量才能使它工作。但它是有效的。我在下面发布了解决方案。