我有一个用户服务,该服务允许登录,注销并维护有关当前登录用户的数据:
ERROR 1049 (42000): Unknown database ' \. schema_belgarath_test_create.sql'
我使用user$ = this.http.get<User>('/api/user')
.pipe(
shareReplay(1),
);
是因为我不想多次调用该Web服务。
为简单起见,在其中一个组件上,我有这个功能,但是如果用户登录,我还有其他几件事要做:
shareReplay(1)
<div *ngIf="isUserLoggedIn$ | async">Logout</div>
但是,isUserLoggedIn$ = this.userService.user$
.pipe(
map(user => user != null),
catchError(error => of(false)),
);
在用户登录或注销后不会更改。刷新页面时确实会更改。
这是我的注销代码:
isLoggedIn$
我知道,如果将变量分配为null,则内部可观察对象不会重置。
因此,对于注销,我从以下答案中得到了提示:https://stackoverflow.com/a/56031703关于刷新logout() {
console.log('logging out');
this.cookieService.deleteAll('/');
this.user$ = null;
console.log('redirecting');
this.router.navigateByUrl('/login');
}
。但是,模板中使用的user $会使我的应用程序在尝试注销时立即陷入困境。
在我的尝试之一中,我尝试了shareReplay()
:
BehaviorSubject
除了刷新页面外,此方法效果更好。 auth-guard(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);
...
}
)始终将用户$作为null并重定向到登录页面。
当我刚开始的时候,这似乎是一件容易的事,但是每次更改我都会陷入一个更深的洞。有解决办法吗?
答案 0 :(得分:2)
对于这种情况,我将数据流(用户)与操作流(用户登录)结合使用,并使用combineLatest
合并两者:
private isUserLoggedInSubject = new BehaviorSubject<boolean>(false);
isUserLoggedIn$ = this.isUserLoggedInSubject.asObservable();
userData$ = this.http.get<User>(this.userUrl).pipe(
shareReplay(1),
catchError(err => throwError("Error occurred"))
);
user$ = combineLatest([this.userData$, this.isUserLoggedIn$]).pipe(
map(([user, isLoggedIn]) => {
if (isLoggedIn) {
console.log('logged in user', JSON.stringify(user));
return user;
} else {
console.log('user logged out');
return null;
}
})
);
constructor(private http: HttpClient) {}
login(): void {
this.isUserLoggedInSubject.next(true);
}
logout(): void {
this.isUserLoggedInSubject.next(false);
}
我这里有一个有效的堆叠闪电战:https://stackblitz.com/edit/angular-user-logout-deborahk
user$
是用户数据流和发出布尔值的isUserLoggedIn$
流的组合。这样,我们可以使用映射并将返回的值映射到用户,如果用户已注销,则将其映射为null。
希望类似的东西对您有用。