Typescript 如何在angularjs2中可观察到的http中添加另一个订阅操作?

Typescript 如何在angularjs2中可观察到的http中添加另一个订阅操作?,typescript,angular,Typescript,Angular,我是安格拉尔的新手。我有一个LoginComponent,它从submit按钮执行一个名为submitLogin的操作。单击时,它将在UtilService的帮助下通过UserService将用户名和密码发送到API服务器。如果服务器响应正常,它将返回一个令牌,我们将在本地保存它并重定向它 到目前为止,我已成功发送用户名和密码并保存令牌。但是,我对如何在LoginComponent中添加另一个操作以便重定向用户感到困惑。我在下面的login.component.ts中添加了一条评论,以澄清我想做

我是安格拉尔的新手。我有一个LoginComponent,它从submit按钮执行一个名为submitLogin的操作。单击时,它将在UtilService的帮助下通过UserService将用户名和密码发送到API服务器。如果服务器响应正常,它将返回一个令牌,我们将在本地保存它并重定向它

到目前为止,我已成功发送用户名和密码并保存令牌。但是,我对如何在LoginComponent中添加另一个操作以便重定向用户感到困惑。我在下面的login.component.ts中添加了一条评论,以澄清我想做什么

如果我没有说清楚,请随时告诉我

以下是我拥有的代码:

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像往常一样订阅。