Angular2 HTTP GET - 将响应转换为完整对象

Dan*_*zel 20 typescript angular

我有这个简单的组件

import {Component} from 'angular2/core';
import {RouterLink, RouteParams} from 'angular2/router';
import {Http, Response, Headers} from 'angular2/http';
import {User} from '../../models/user';
import 'rxjs/add/operator/map';


@Component({
    template: `
        <h1>{{user.name}} {{user.surname}}</h1>
    `,
    directives: [RouterLink],
})
export class UserComponent {

    user: User;

    constructor(private routeParams: RouteParams,
        public http: Http) {
            this.user = new User();
            this.http.get('http://localhost:3000/user/' + this.routeParams.get('id'))
                .map((res: Response) => res.json())
                .subscribe((user: User) => this.user = user);
        console.log(this.user);
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么不subscribe将响应转换为完整User对象.当我记录user变量时,我的控制台说User {_id: undefined, name: undefined, surname: undefined, email: undefined}.但是在视图中绑定.name并且.surname正在工作..

这里发生了什么?用户实际存储在哪里?

Dan*_*zel 20

在这里找到了解决方案:https://stackoverflow.com/a/29759472/2854890

我的方法现在看起来像这样:

constructor(private routeParams: RouteParams,
    public http: Http) {
    this.user = new User();
    this.http.get('http://localhost:3000/user/' + this.routeParams.get('id'))
        .map((res: Response) => res.json())
        .subscribe((json: Object) => {
            this.user = new User().fromJSON(json);
        });
}
Run Code Online (Sandbox Code Playgroud)

Serializable通过最后返回对象来增强它,所以我可以省略类似的东西

var u = new User();
u.fromJSON(...);
Run Code Online (Sandbox Code Playgroud)

然后写

new User().fromJSON(json);
Run Code Online (Sandbox Code Playgroud)

Serializable

export class Serializable {

    fromJSON(json) {
        for (var propName in json)
            this[propName] = json[propName];
        return this;
    }

}
Run Code Online (Sandbox Code Playgroud)


Prz*_*ski 19

好的做法是使用GET响应来使用数据

Observable<Model>
Run Code Online (Sandbox Code Playgroud)

(关于Angular文档https://angular.io/guide/http)所以......

//进口

import {HttpClient} from "@angular/common/http";
Run Code Online (Sandbox Code Playgroud)

//在构造函数参数列表中

private http: HttpClient
Run Code Online (Sandbox Code Playgroud)

//服务方法

getUser(): Observable<User> {return this.http.get<User>({url}, {options});}
Run Code Online (Sandbox Code Playgroud)

您不需要再做任何事情了.我认为这种方法最友好.

  • 这适用于大多数方法,但它不会转换,更像是类型断言.如果你的类中有一个函数`export class User {test(){console.log("works"); 你无法运行user.test(). (36认同)
  • 为了避免混淆任何人,这种方法仅适用于Angular 4.3+,其中引入了新的HttpClient. (4认同)
  • 作者的问题是他的`log`命令在响应到来之前执行.在我的观点中,你的答案与作者的问题无关.此外,他要求一个"完整的`User`对象",我将其解释为`User`类实例.因此,即使他的日志正确,你的答案也是错误的,因为它将返回一个普通的对象(如上面指出的ovmcit5eoivc4) (2认同)