我有一个用户服务,它允许登录、注销并维护有关当前登录用户的数据:
user$ = this.http.get<User>('/api/user')
.pipe(
shareReplay(1),
);
我使用 shareReplay(1)
因为我不想多次调用 web 服务。
在其中一个组件上,我有这个(为简单起见),但如果用户登录,我还有其他几件事要做:
<div *ngIf="isUserLoggedIn$ | async">Logout</div>
isUserLoggedIn$ = this.userService.user$
.pipe(
map(user => user != null),
catchError(error => of(false)),
);
但是, isLoggedIn$
在用户登录或注销后不会更改。当我刷新页面时它确实会改变。
这是我的注销代码:
logout() {
console.log('logging out');
this.cookieService.deleteAll('/');
this.user$ = null;
console.log('redirecting');
this.router.navigateByUrl('/login');
}
我知道如果我将变量分配给 null,内部 observable 不会重置。
因此,对于注销,我从这个答案中得到了线索: https://stackoverflow.com/a/56031703 关于刷新 shareReplay()
。但是,模板中使用的 user$ 会导致我的应用程序在我尝试注销时立即陷入困境。
在我的一次尝试中,我尝试了 BehaviorSubject
:
user$ = new BehaviorSubject<User>(null);
constructor() {
this.http.get<User>('/api/user')
.pipe(take(1), map((user) => this.user$.next(user))
.subscribe();
}
logout() {
...
this.user$.next(null);
...
}
除非我刷新页面,否则这会更好一些。 auth-guard ( CanActivate
) 总是将 user$ 设为 null 并重定向到登录页面。
当我刚开始时,这似乎是一件容易的事,但每次更改我都会陷入更深的困境。有针对这个的解决方法吗?