Angular2 HTTP GET - 将响应转换为完整对象
Posted
技术标签:
【中文标题】Angular2 HTTP GET - 将响应转换为完整对象【英文标题】:Angular2 HTTP GET - Cast response into full object 【发布时间】:2016-07-01 01:30:29 【问题描述】:我有这个简单的组件
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);
为什么subscribe
不将响应转换为完整的User
对象。当我记录user
变量时,我的控制台说User _id: undefined, name: undefined, surname: undefined, email: undefined
。但尽管如此,绑定到视图中的.name
和.surname
是有效的..
这里发生了什么?用户实际存储在哪里?
【问题讨论】:
How do I cast a JSON object to a typescript class的可能重复 我看了这篇文章也不错***.com/questions/63964124/… 【参考方案1】:TypeScript 不支持。
请参阅How do I cast a JSON object to a typescript class 了解更多详情。
【讨论】:
但是为什么我仍然能够绑定到数据。它被显示,而我绑定的变量被记录为未定义.. 那么绑定如何工作 JSON 和对象在 TypeScript/JS 中是可以互换的,但是创建的对象只会包含 JSON 所包含的内容,而不会包含仅在真实类的原型中定义的方法或其他字段。跨度> 如果我把它改成.subscribe(data => this.user = new User(data._id, data.name, data.surname, data.email));
,日志还是一样的。我需要登录什么才能获取视图绑定的对象?
我还漏掉了另一个错误。 `console.log(this.user);` 在发出 HTTP 请求之前执行。 this.http.get()
是异步的,这意味着任务在浏览器事件队列中排队等待稍后执行,然后继续执行 JS(使用您的 log 命令)。当 HTTP 调用完成后,将执行传递给 .subscribe(...)
的回调,但这要晚得多。将日志调用移至subscribe((user: User) => ... );
【参考方案2】:
在这里找到解决方案:https://***.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);
);
我通过最后返回对象来增强Serializable
,所以我可以省略类似
var u = new User();
u.fromJSON(...);
然后写
new User().fromJSON(json);
Serializable
类
export class Serializable
fromJSON(json)
for (var propName in json)
this[propName] = json[propName];
return this;
【讨论】:
在 Angular 6 中 map() 行给出错误:Argument of type '(res: Response) => Promise<any>' is not assignable to parameter of type '(value: Response, index: number) => Promise<any>'.
地图在 Angular 6 中发生了变化。检查一下:academind.com/learn/angular/snippets/…
@DanielHitzel 您最初的问题是您的console.log
在响应到达之前执行。即使它位于正确的位置,您也会用一个普通对象 (this.user = user
) 覆盖您的 subscribe
处理程序中的值,该对象不再是 User
的实例(尽管如此,User
兼容对象具有相同的特性)。这个答案解决了这两个问题。但是,我想指出您的实际问题 - 属性值为 undefined
- 源于另一个错误。
以更多经验查看代码,是的,这似乎是真的:D【参考方案3】:
良好的做法是使用来自 GET 响应的数据
Observable<Model>
(关于 Angular 文档https://angular.io/guide/http) 所以……
// 进口
import HttpClient from "@angular/common/http";
//在构造函数参数列表中
private http: HttpClient
//服务方法
getUser(): Observable<User> return this.http.get<User>(url, options);
您无需再做任何事情。我认为这种方法最友好。
【讨论】:
这适用于大多数方法,但它不会强制转换,更像是类型断言。如果你的类中有函数export class User test() console.log("works");
你不能运行 user.test()。
为了避免让任何人感到困惑,这种方法仅在引入新 HttpClient 的 Angular 4.3+ 中可用。
@DarrenLewis,如果 get 方法想要返回 Model 数组,我们必须使用什么方法?
@Anil 此方法也适用于模型数组。只是代替 User 你把 User[]
作者的问题是他的log
命令在响应到达之前就执行了。在我看来,您的回答与作者的问题完全无关。此外,他要求一个“完整的User
对象”,我将其解释为User
类实例。因此,即使他的日志位于正确的位置,您的答案也将是错误的,因为它将返回一个普通对象(如 ovmcit5eoivc4 上面指出的那样)以上是关于Angular2 HTTP GET - 将响应转换为完整对象的主要内容,如果未能解决你的问题,请参考以下文章
某些 GET 请求对预检的 Angular2 响应无效(重定向)
Angular2:http.get 返回“请求的资源上不存在‘Access-Control-Allow-Origin’标头。”