处理嵌套的可观察对象
Handling nested observables
我在 Angular 2 开始一个项目,这是我第一次处理 Observables,对一个非常具体的案例有一些疑问。
我有一个 API 服务是这样的:
@Injectable()
export class UserAPI {
[...]
login(email: string, password: string): Observable<Response> {
let params = new URLSearchParams();
params.set('email', email);
params.set('password', password);
return this.$http.request(
new Request({
method: RequestMethod.Post,
url: this.baseUrl + '/login',
search: params
}))
.map((response: Response) => response.json());
}
[...]
}
我在用户服务上管理用户会话及其配置文件数据(当其会话处于活动状态时),该服务包含调用此 API:
的方法
@Injectable()
export class UserService {
[...]
constructor(private userAPI: UserAPI, private storage: StorageService) {
}
login(email: string, password: string) {
return this.userAPI.login(email, password).subscribe(
(res) => {
this.storage.store(Constants.storage.session, res.token);
},
(err) => {
this.storage.destroy(Constants.storage.session);
}
);
}
[...]
}
现在,我还有一个处理登录表单的组件,如果成功,会将用户重定向到应用程序的私有区域,但如果失败,则会显示错误消息 (401 , 或者任何其他偶然发生的错误):
@Component({
moduleId: module.id,
selector: "auth-login",
templateUrl: "auth.login.html"
})
export class LoginComponent {
constructor(private router: Router, private userService: UserService) {
}
[...]
login(): void {
this.form.loading = true;
this.form.error = -100; // arbitrary number
this.userService.login(this.form.email, this.form.password);
/*
.subscribe(
(res) => {
this.router.navigate(["/home", {}]);
},
(err) => {
this.form.error = err.status;
},
() => {
this.form.loading = false;
}
);
*/
}
[...]
}
请注意 userService.login()
函数调用中的注释代码。这些是我打算对调用的 success/error 执行的说明,但我无法让它工作。我想把事情分开:用户服务管理会话部分,组件处理重定向或向用户显示出了什么问题。
我做错了什么?到这里怎么走?嵌套的可观察对象?在组件和用户服务之间使用承诺?其他一些方法?我一直在搜索这里,但找不到与我的相似的案例。
我不认为你可以像那样链接订阅;您实际上期望 thing.subscribe(...).subscribe(...)
工作。相反,您可以将 .map
and .catch
用于服务内的操作,并让组件 .subscribe
:
login(email: string, password: string) {
return this.userAPI.login(email, password)
.map(res => {
this.storage.store(Constants.storage.session, res.token);
return res;
})
.catch(err => {
this.storage.destroy(Constants.storage.session);
return Observable.throw(err);
});
}
我在 Angular 2 开始一个项目,这是我第一次处理 Observables,对一个非常具体的案例有一些疑问。
我有一个 API 服务是这样的:
@Injectable()
export class UserAPI {
[...]
login(email: string, password: string): Observable<Response> {
let params = new URLSearchParams();
params.set('email', email);
params.set('password', password);
return this.$http.request(
new Request({
method: RequestMethod.Post,
url: this.baseUrl + '/login',
search: params
}))
.map((response: Response) => response.json());
}
[...]
}
我在用户服务上管理用户会话及其配置文件数据(当其会话处于活动状态时),该服务包含调用此 API:
的方法@Injectable()
export class UserService {
[...]
constructor(private userAPI: UserAPI, private storage: StorageService) {
}
login(email: string, password: string) {
return this.userAPI.login(email, password).subscribe(
(res) => {
this.storage.store(Constants.storage.session, res.token);
},
(err) => {
this.storage.destroy(Constants.storage.session);
}
);
}
[...]
}
现在,我还有一个处理登录表单的组件,如果成功,会将用户重定向到应用程序的私有区域,但如果失败,则会显示错误消息 (401 , 或者任何其他偶然发生的错误):
@Component({
moduleId: module.id,
selector: "auth-login",
templateUrl: "auth.login.html"
})
export class LoginComponent {
constructor(private router: Router, private userService: UserService) {
}
[...]
login(): void {
this.form.loading = true;
this.form.error = -100; // arbitrary number
this.userService.login(this.form.email, this.form.password);
/*
.subscribe(
(res) => {
this.router.navigate(["/home", {}]);
},
(err) => {
this.form.error = err.status;
},
() => {
this.form.loading = false;
}
);
*/
}
[...]
}
请注意 userService.login()
函数调用中的注释代码。这些是我打算对调用的 success/error 执行的说明,但我无法让它工作。我想把事情分开:用户服务管理会话部分,组件处理重定向或向用户显示出了什么问题。
我做错了什么?到这里怎么走?嵌套的可观察对象?在组件和用户服务之间使用承诺?其他一些方法?我一直在搜索这里,但找不到与我的相似的案例。
我不认为你可以像那样链接订阅;您实际上期望 thing.subscribe(...).subscribe(...)
工作。相反,您可以将 .map
and .catch
用于服务内的操作,并让组件 .subscribe
:
login(email: string, password: string) {
return this.userAPI.login(email, password)
.map(res => {
this.storage.store(Constants.storage.session, res.token);
return res;
})
.catch(err => {
this.storage.destroy(Constants.storage.session);
return Observable.throw(err);
});
}