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

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

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

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


person RiesvGeffen    schedule 03.04.2018    source источник


Ответы (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>
person Tomasz Kula    schedule 03.04.2018
comment
Отлично работает! Нормально это работало бы правильно? Но поскольку я использую async, мне приходится использовать круглые скобки. - person RiesvGeffen; 03.04.2018
comment
Да, но здесь нужно сначала применить пайп, а потом отрицание :) - person Tomasz Kula; 03.04.2018
comment
@SjaakvBrabant проверьте мою правку с другим возможным рефакторингом :) - person Tomasz Kula; 03.04.2018
comment
Да, я просто смотрел на это. Но в чем причина ‹ng-container›, а не просто ‹div›? РЕДАКТИРОВАТЬ: на самом деле это не работает, кнопка входа в систему никогда не появляется. - person RiesvGeffen; 03.04.2018
comment
Если вы используете <ng-container>, он не будет вставлять какие-либо узлы DOM. Он сохранит вашу разметку как есть. Здесь это может не иметь значения, но в некоторых случаях будет. Например, у вас могут быть некоторые стили css, примененные к родительскому элементу вашей ссылки, а другой div там испортит его. Обычно <ng-container> исчезает во время выполнения, но вы все равно можете настроить таргетинг с помощью * ngIf, * ngFor и т. Д. :) - person Tomasz Kula; 03.04.2018
comment
@TomaszKula ваше решение работает отлично, за исключением перезагрузки страницы. Когда я сильно перезагружаю страницу, сначала будет отображаться кнопка входа в систему, а когда страница будет сфокусирована с помощью клавиатуры или мыши, она будет обновлена ​​до выхода. Я могу понять, что начальное значение наблюдателя ложно, поэтому сначала будет отображаться кнопка входа в систему. Но не думаете ли вы, что он должен быть обновлен до выхода из системы, как только значение наблюдателя обновится? Ты хоть представляешь, почему это происходит? - person Darpan; 11.06.2019
comment
Я использую тот же самый код, но у меня не получалось (Angular 6). Я подозреваю, что мой ng-контейнер не отображает его содержимое, потому что isLoggedIn переводится в false. Так что у якорей нет возможности проверить свои * ngIfs. В итоге я использовал метод; else templateName. Но я предпочитаю использовать ng-контейнер. Я делаю что-то неправильно? Это также произошло в другом случае, когда наблюдаемое было объектом или null = ›тем же результатом. - person Robin; 25.06.2019
comment
Второй пример неверен, как только isLoggedIn$ излучает false, весь <ng-container> удаляется. - person isevcik; 03.12.2019

Вы также можете выполнить рефакторинг для использования части else в директиве 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>

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

person Adrian Fâciu    schedule 03.04.2018
comment
Не знаю почему, но раньше я этого не понимал. Потому что я просмотрел документы, но ничего не понял. Но теперь вы сделали это в моем контексте, я понимаю это и буду помнить об этом решении. Спасибо за помощь! - person RiesvGeffen; 03.04.2018