我有导航栏组件,我的目标是根据用户登录显示两个不同的导航栏,即,如果用户登录,他们将看到一个导航栏;如果没有的话,另一个。我正在使用ngIf,并且一切正常,除了登录用户仍然看到未登录用户的导航栏,直到他们手动刷新页面为止。
import {Component, OnInit} from '@angular/core';
import {User} from '@models/user.model';
import {AuthenticationService} from '@services/auth.service';
import {Observable} from 'rxjs';
@Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
user: User;
authObs: Observable<User>;
constructor(private auth_service: AuthenticationService) { }
ngOnInit() {
this.authObs = this.auth_service.currentUser;
}
<nav *ngIf="authObs | async as auth; else elseBlock" class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav">
<li class="nav-item sub">
<a class="nav-link unselectable" (click)="gt_myprofile()"><span class="icon icon-profile"></span> my
profile</a>
</li>
<li class="nav-item sub">
<a class="nav-link unselectable" (click)="gt_messages()"><span class="icon icon-message"></span> messages
<span
class="icon-notif"></span> </a>
</li>
<li class="nav-item sub">
<a class="nav-link unselectable" (click)="gt_contacts()"><span class="icon icon-contacts"></span>
contacts<span
class="icon-notif"></span> </a>
</li>
</ul>
</div>
</div>
</nav>
<ng-template #elseBlock>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="#"><img src="assets/static" alt=""></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<!-- start navbar-nav -->
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="#">about<span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">cooperation</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">terms</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">contacts</a>
</li>
</ul>
</div>
</div>
</nav>
</ng-template>
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { User } from '@models/user.model';
@Injectable({ providedIn: 'root' })
export class AuthenticationService {
private currentUserSubject: BehaviorSubject<User>;
public currentUser: Observable<User>;
constructor(private http: HttpClient) {
this.currentUserSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem('currentUser')));
this.currentUser = this.currentUserSubject.asObservable();
}
public get currentUserValue(): User {
return this.currentUserSubject.value;
}
}
login(email: string, password: string) {
return this.http.post<any>(`${environment.apiUrl}/api/auth/`, { email, password })
.pipe(map(user => {
// store user details and jwt token in local storage to keep user logged in between page refreshes
localStorage.setItem('currentUser', JSON.stringify(user));
this.currentUserSubject.next(user);
this.currentUser = this.currentUserSubject.asObservable();
console.log("TCL: AuthenticationService -> login -> user", user)
return user;
}));
}
答案 0 :(得分:0)
我认为问题在于s0,s1,s3
没有发出新值,否则* ngIf和异步管道使用情况看起来不错。
如何调用/使用authService更新登录信息?
如果您更新localStorage信息以反映该用户是否已登录,则应发出该主题的新值,例如:
authService
您可以在用户登录后或要更新currentUser状态时调用此方法。这取决于您的代码逻辑,但是发出新值很重要,否则您的主题将永远不会通知订户可以使用新值。
您是否尝试过调试authObs变量并将其值打印在模板中?
updateUserAuth(newValue) {
this.currentUserSubject.next(newValue);
this.currentUser = this.currentUserSubject.asObservable();
}
我认为您也可以跳过构造函数中的currentUser初始化(或者是否始终将用户信息存储在本地,直到显式注销为止?):
<.. *ngIf="authObs | async as auth; else elseBlock">
Auth: {{auth}}
最终可以用您的代码创建一个stackBlitz示例吗?