*ng Если не работает должным образом с наблюдаемым

Итак, у меня есть эти 2 кнопки:

<a class="router-link nav-item" routerLink="/login" *ngIf="!isLoggedIn$ | async">
  Login
</a>
<a class="router-link nav-item" (click)="onLogout()" *ngIf="isLoggedIn$ | async">
  Logout
</a>

И кнопка выхода из системы работает отлично, как только пользователь вошел в систему, кнопка появляется. Но кнопка входа никогда не появляется.

Это код за isLoggedIn$:

isLoggedIn$: Observable<boolean>;

ngOnInit() {
  this.isLoggedIn$ = this.authService.isLoggedIn;
}

AuthService:

private loggedIn = new BehaviorSubject<boolean>(false);

get isLoggedIn() {
  return this.loggedIn.asObservable();
}

Надеюсь, что это достаточно информации, и проблема ясна, заранее спасибо!

5 ответов

Решение

Поместите асинхронную трубу в скобки.

<a class="router-link nav-item" routerLink="/login" *ngIf="!(isLoggedIn$ | async)">
  Login
</a>
<a class="router-link nav-item" (click)="onLogout()" *ngIf="isLoggedIn$ | async">
  Logout
</a>

Вы также можете рассмотреть возможность рефакторинга вышеупомянутого фрагмента с помощью as ключевое слово введено в Angular 4:

<ng-container *ngIf="isLoggedIn$ | async as isLoggedIn">
   <a class="router-link nav-item" routerLink="/login" *ngIf="!isLoggedIn">
    Login
  </a>
  <a class="router-link nav-item" (click)="onLogout()" *ngIf="isLoggedIn">
    Logout
  </a>
</ng-container>

Подробнее о as синтаксис в официальных документах.

Вы также можете изменить рефакторинг для использования другой части директивы ngIf:

<a class="router-link nav-item" (click)="onLogout()" *ngIf="isLoggedIn$ | async; else loginBlock">
    Logout
</a>
<ng-template #loginBlock>
    <a class="router-link nav-item" routerLink="/login">
        Login
    </a>
</ng-template>

Вы можете увидеть больше примеров в документах.

Мне нравится ответ с *ngIf and Elseподход, но ваша версия также может быть оптимизирована для предотвращения двойной подписки.

      <ng-container *ngIf="{ isLoggedIn: (isLoggedIn$ | async) } as observables">
  <a class="router-link nav-item" routerLink="/login" *ngIf="!observables.isLoggedIn">
    Login
  </a>
  <a class="router-link nav-item" (click)="onLogout()" *ngIf="observables.isLoggedIn">
  Logout
  </a>
</ng-container>

В Angular версии 14 это работает для меня:

Вы также можете подписаться на функцию isLoggedIn() вместо использования obsevable с асинхронным каналом:

      isLoggedIn: boolean;

ngOnInit() {
  this.isLoggedIn = this.authService.isLoggedIn().subscribe(res => {
       this.isLoggedIn = res;
  });
}

Теперь вы можете просто использовать isLoggedIn в Html:

      <a class="router-link nav-item" routerLink="/login" *ngIf="!isLoggedIn">
 Login
</a>

<a class="router-link nav-item" (click)="onLogout()" *ngIf="isLoggedIn">
Logout
</a>
Другие вопросы по тегам