Typescript 如何在angularjs2中可观察到的http中添加另一个订阅操作?
我是安格拉尔的新手。我有一个LoginComponent,它从submit按钮执行一个名为submitLogin的操作。单击时,它将在UtilService的帮助下通过UserService将用户名和密码发送到API服务器。如果服务器响应正常,它将返回一个令牌,我们将在本地保存它并重定向它 到目前为止,我已成功发送用户名和密码并保存令牌。但是,我对如何在LoginComponent中添加另一个操作以便重定向用户感到困惑。我在下面的login.component.ts中添加了一条评论,以澄清我想做什么 如果我没有说清楚,请随时告诉我 以下是我拥有的代码: login.component.ts具有以下功能:Typescript 如何在angularjs2中可观察到的http中添加另一个订阅操作?,typescript,angular,Typescript,Angular,我是安格拉尔的新手。我有一个LoginComponent,它从submit按钮执行一个名为submitLogin的操作。单击时,它将在UtilService的帮助下通过UserService将用户名和密码发送到API服务器。如果服务器响应正常,它将返回一个令牌,我们将在本地保存它并重定向它 到目前为止,我已成功发送用户名和密码并保存令牌。但是,我对如何在LoginComponent中添加另一个操作以便重定向用户感到困惑。我在下面的login.component.ts中添加了一条评论,以澄清我想做
import {Component, OnInit} from 'angular2/core';
import {NgForm} from 'angular2/common';
import {UserService} from '../services/user.service';
@Component({
selector: 'login',
templateUrl: './components/login/login.component.html',
styleUrls: ['./components/login/login.component.css']
})
export class LoginComponent implements OnInit {
public username: string;
public password: string;
public loginResult: string;
constructor(private _userService: UserService) {}
ngOnInit() { }
submitLogin() {
var p = this._userService.login(this.username, this.password);
// HOW TO:
// I know p is an observable. But, is it possible to add a condition as follow:
// if p is success, then redirect
// if p failed, then return
}
}
user.service.ts:
import {Injectable} from 'angular2/core';
import {UtilsService} from './utils.service';
@Injectable()
export class UserService {
constructor(private _utils: UtilsService) { }
login(username: string, password: string) {
var request = {
method: 'POST',
headers: { 'Authorization': 'Basic ' + btoa(username + ':' + password) },
url: '/auth/',
data: null
};
return this._utils.api(request).subscribe(
data => this.setAccessToken(data.json().access_token),
err => console.log(err)
);
var promise = this._utils.api(request);
promise.then((response) => {
this.setAccessToken(response.token);
});
}
}
import {Injectable} from 'angular2/core';
import {Http, Headers} from 'angular2/http';
@Injectable()
export class UtilsService {
private apiUrl: string;
constructor(public http: Http) {
this.apiUrl = '/api/1';
}
api(request: any) {
var headers = new Headers();
var url = this.apiUrl + request.url;
if(request.headers) {
for(var key in request.headers) {
headers.append(key, request.headers[key]);
}
}
if(!request.type || request.type === 'GET') {
return this.http.get(url, { headers: headers });
}
if(request.type === 'POST') {
return this.http.post(url, request.data, { headers: headers });
}
if(request.type === 'PUT') {
return this.http.put(url, request.data, { headers: headers });
}
if(request.type === 'DELETE') {
return this.http.delete(url, { headers: headers });
}
return false;
}
}
utils.service.ts:
import {Injectable} from 'angular2/core';
import {UtilsService} from './utils.service';
@Injectable()
export class UserService {
constructor(private _utils: UtilsService) { }
login(username: string, password: string) {
var request = {
method: 'POST',
headers: { 'Authorization': 'Basic ' + btoa(username + ':' + password) },
url: '/auth/',
data: null
};
return this._utils.api(request).subscribe(
data => this.setAccessToken(data.json().access_token),
err => console.log(err)
);
var promise = this._utils.api(request);
promise.then((response) => {
this.setAccessToken(response.token);
});
}
}
import {Injectable} from 'angular2/core';
import {Http, Headers} from 'angular2/http';
@Injectable()
export class UtilsService {
private apiUrl: string;
constructor(public http: Http) {
this.apiUrl = '/api/1';
}
api(request: any) {
var headers = new Headers();
var url = this.apiUrl + request.url;
if(request.headers) {
for(var key in request.headers) {
headers.append(key, request.headers[key]);
}
}
if(!request.type || request.type === 'GET') {
return this.http.get(url, { headers: headers });
}
if(request.type === 'POST') {
return this.http.post(url, request.data, { headers: headers });
}
if(request.type === 'PUT') {
return this.http.put(url, request.data, { headers: headers });
}
if(request.type === 'DELETE') {
return this.http.delete(url, { headers: headers });
}
return false;
}
}
如果您将UserService.login返回设置为可观察而不是订阅服务器,那么现在您可以在LoginComponent中订阅它
export class UserService {
login(username: string, password: string) {
return this._utils.api(request)
.map(response => response.json())
);
}
}
export class LoginComponent implements OnInit {
submitLogin() {
var p = this._userService
.login(this.username, this.password)
.subscribe(
// success
(data) => {
this._userService.setAccessToken(data.access_token);
// redirect here...
},
// error
(error) => {},
// completed
() => {}
)
}
}
您还可以使用add方法向subscribe方法返回的订阅服务器添加另一个订阅,但我相信我们应该习惯返回obeservables的服务:非常感谢您的澄清@Sasxa,我想知道这个错误,不知怎的,我变得像一个e{{u body:{error:User-not-found.},状态:404,状态文本:Ok,标题:e,类型:2…}。如何从中获取“未找到用户”的错误消息?谢谢成功处理程序和错误处理程序都有一个字符串,您可以调用它的json方法来获取消息感谢您的回复。我也是这么想的。在上面的utils.service.ts中,我在返回行的末尾添加了.mapres:Response=>res.json。我设法将成功返回的数据作为JSON对象获取。但是,不知何故,错误仍然会返回一个响应。有什么我该做的吗?再次非常感谢!您可以直接在UserService登录方法中设置访问令牌,因为OP正在尝试使用.do来执行此操作,而不必从LoginComponent对服务进行第二次调用:返回此值。_utils.apirest.mapres=>res.json.dodata=>this.setAccessTokendata.token;。然后LoginComponent像往常一样订阅。