如何将响应从http.get映射到Angular 2中的类型化对象的新实例

Mag*_*röm 16 http-get observable rxjs typescript angular

我试图了解如何使用Angular 2中的http.get和Observables将服务调用的结果映射到对象.

看看这个Plunk

在方法getPersonWithGetProperty中,我期望返回一个类型为PersonWithGetProperty的Observable.然而!我无法访问属性fullName.我想我必须创建PersonWithGetProperty类的新实例,并使用类构造函数将响应映射到这个新对象.但是你如何在方法getPersonWithGetProperty中做到这一点?

import {Injectable} from '@angular/core';
import {Http, Response} from '@angular/http';
import {Observable} from 'rxjs/Rx';

export class PersonWithGetProperty {
  constructor(public firstName: string, public lastName: string){}

  get fullName(): string {
    return this.firstName + ' ' + this.lastName;
  }
}

@Injectable()
export class PersonService {
    constructor(private http: Http) {
    }

    getPersonWithGetProperty(): Observable<PersonWithGetProperty> {
        return this.http.get('data/person.json')
         .map((response: Response) => <PersonWithGetProperty>(response.json()));
    }
}
Run Code Online (Sandbox Code Playgroud)

pau*_*els 26

问题是你正在强制解析的json表现得像类一样.

应用<PersonWithGetProperty>实际上并没有创建它的新实例PersonWithGetProperty只是告诉编译器关闭,因为你知道你在做什么.如果要实际创建实例PersonWithGetProperty,则需要使用它来构造它new.

幸运的是,你已经到了一半,只需map在解析输出后添加另一个:

@Injectable()
export class PersonService {
    constructor(private http: Http) {
    }

    getPersonWithGetProperty(): Observable<PersonWithGetProperty> {
        return this.http.get('data/person.json')
         .map((response: Response) => response.json())
         .map(({firstName, lastName}) => new PersonWithGetProperty(firstName, lastName));
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑

为此,您需要确保使用RxJS 5:

import 'rxjs/add/operator/map'
Run Code Online (Sandbox Code Playgroud)

如果您希望将来安全,您应该使用pipeRxJS 5的更高版本中引入的语法

// Either
import {map} from 'rxjs/operators'

return this.http.get('data/person.json').pipe(
  map((response: Response) => response.json()),
  map(({firstName, lastName}) => new PersonWithGetProperty(firstName, lastName))
);
Run Code Online (Sandbox Code Playgroud)