我有一个应用程序在哪里注销用户,我必须点击一个REST endpoints . 在我的角度2前端,我有以下服务处理这个:
@Injectable()
export class AuthService {
private authEvents: Subject<boolean>;
constructor(private http: Http) {
this.authEvents = new Subject<boolean>();
}
login(email: string, password: string): Observable<Response> {
const url = 'rest/auth/login';
const body = {
email: email,
password: password
};
return this.http.post(url, body)
.do((res: Response) => {
localStorage.setItem('currentUser', JSON.stringify(res.json()));
this.authEvents.next(true);
});
}
logout(): Observable<Response> {
const url = 'rest/auth/logout';
return this.http.post(url, {})
.do((res: Response) => {
localStorage.removeItem('currentUser');
console.log('hereee!');
this.authEvents.next(false);
});
}
isSignedIn(): boolean {
return localStorage.getItem('currentUser') !== null;
}
get events(): Observable<boolean> {
return this.authEvents;
}
}
让我解释一下我在这里要做的事情 . 我有一个 authEvents
主题,我在我的组件中订阅如下:
ngOnInit() {
this.isSignedIn = this.authService.isSignedIn();
this.authService.events.subscribe(() => {
this.isSignedIn = this.authService.isSignedIn();
});
}
当用户单击注销按钮时,我在此组件中调用以下函数:
logout() {
this.authService.logout()
.subscribe(() => {
this.router.navigate(['/home']);
}, e => this.handleError(e));
}
问题是即使注销调用尚未完成,浏览器也会重定向到home . 如此有效,有时候前端会成功退出,有时则不会!我在这做错了什么?
注意:自http呼叫发生以来,后端上的会话始终会注销 . 我还想看看如何使用Observables(和一般的rxjs)来实现这一点,尽管如果太麻烦,可以使用Promises .
2 回答
有了
Subject
,您就有这样的情况,即排放仅由订阅者接收,而不是由未来的订阅者接收 . 我的猜测是,这是你的问题 - 为了让你的生活更轻松,你可以使用BehaviorSubject
,它也可以为任何未来的用户重新发布它的当前 Value ,所以你不必担心任何比赛 - 条件 .However: 严格地说它不再是一个事件,而是更多的一个状态,这是我建议你在你的情况下使用的 - 因为使用RxJS你可以利用状态的力量而不是事件 .
在您的组件中
由于RxJS5文档尚未包含BehaviorSubject,因此这里是旧文档的链接:https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md
这对我有用:
正如@olsn建议的那样,我将
Subject
更改为BehaviorSubject
.但实际上在组件的html中出现了什么问题 .
我必须在
(click)
事件中添加$event.preventDefault()
调用,所有内容似乎都按预期工作 . 虽然有人可以向我解释为什么会这样,但这会很棒!