Angular 5 / Typescript - 如何将复杂的 json 对象转换为类
Posted
技术标签:
【中文标题】Angular 5 / Typescript - 如何将复杂的 json 对象转换为类【英文标题】:Angular 5 / Typescript - How to cast complex json object to a class 【发布时间】:2018-05-17 21:47:06 【问题描述】:我正在尝试将一个复杂的(多个类型类)json 响应对象(我从我的 nodejs/mongoose 后端接收)转换为一个打字稿类。
moment 类包含用户类型的作者和评论类型的 cmets 数组。
moment.model.ts
import Comment from './comment.model';
import User from './user.model';
export class Moment
_id?: string = null;
body?: string = null;
_author?: User = null;
likes?: any[] = [];
dislikes?: any[] = [];
_comments?: Comment[] = [];
created_at?: string = null;
updated_at?: string = null;
constructor(data?: Moment)
console.log(data);
if (data)
this.deserialize(data);
private deserialize(data: Moment)
const keys = Object.keys(this);
for (const key of keys)
if (data.hasOwnProperty(key))
this[key] = data[key];
public get author(): User
return this._author;
public set author(data: User)
this._author = new User(data);
public get comments(): Comment[]
return this._comments;
public set comments(data: Comment[])
this._comments = data.map(c => new Comment(c));
comment.model.ts
export class Comment
_id?: string = null;
body?: string = null;
moment?: any = null;
author?: any = null;
likes?: any[] = [];
dislikes?: any[] = [];
parent?: any = null;
replies?: any = null;
updated_at?: string = null;
created_at?: string = null;
constructor(data?: Comment)
console.log(data);
if (data)
this.deserialize(data);
private deserialize(data: Comment)
const keys = Object.keys(this);
for (const key of keys)
if (data.hasOwnProperty(key))
this[key] = data[key];
user.model.ts
export class User
_id?: string = null
updated_at?: string = null;
created_at?: string = null;
profile?: any = null;
phone?: any = null;
email?: any = null;
followers: any[] = [];
following: any[] = [];
isOnline: any = null;
socketId: any = null;
constructor(data?: User)
console.log(data);
if (data)
this.deserialize(data);
private deserialize(data: User)
const keys = Object.keys(this);
for (const key of keys)
if (data.hasOwnProperty(key))
this[key] = data[key];
moment.service.ts
get(moment_id)
let endpoint = this.path + moment_id;
return this.apiService.get(endpoint)
.map((res) => new Moment(res.data));
moment-detail.component.ts
this.route.params.switchMap((params) =>
let moment_id = params['id'];
return this.momentService.get(moment_id);
).subscribe((res) =>
this.moment = res;
console.log(this.moment);
);
当我调用我的服务时,我将 json 分配给一个新的 Moment 类。然后在组件中尝试打印 this.moment。一切都很好,除了作者和一个空/空的 cmets。
【问题讨论】:
_author
是User
类型,只有当你像new User( data[key])
这样调用时,值才会分配给_author 的成员。否则,由于类型兼容性,您将收到错误并给出预期的 null。
如果你带一个 Moment 的例子,我们可以更容易地测试它。你不觉得吗?另外我认为你应该删除 javascript 标签,因为在这段代码中没有任何 javascript 代码(即使你使用 node.js 作为后端)。就像好奇一样,为什么要使用复制构造函数(在构造函数内部反序列化)?你真的需要它吗?
@SantoshHegde ye 我想我理解这个问题,有解决方案吗?
@JTejedor 是的,我需要它,这就是重点,我试图将 json 数据转换为 typescript 类。
这不是真正的铸造。您正在构建一个 Moment
(与 new Moment
),但我没有看到其他类在任何地方被调用?
【参考方案1】:
你可以试试
this[key]=( key=='_author' ? new User(data[key]):(key=='_comments'?new Comment(data[key]): data[key]))
或者
if(key=='_author')
this[key]=new User(data[key]);
else if(key=='_comments')
this[key]=new Comment(data[key]);
else
this[key]=data[key]
【讨论】:
谢谢你,虽然这不是它帮助我的正确解决方案 最好重写你的代码。写的不好。【参考方案2】:Moment
中的 deserialize
方法以相同的方式处理每个字段,只是从 JSON 中复制值。这意味着它永远不会构造 User
或 Comment
对象。您可能应该“手动”编写它以正确处理每个属性,而不是使用循环。
【讨论】:
是的,我不需要 getter 和 setter,只需要重建我的班级。我只是想知道这是多么有效。 高效在什么意义上?很少值得担心这样的事情的运行时效率。更重要的是考虑可维护性。 对不起,这就是我的意思,我试图将一些与时刻相关的函数重构到模型中,而不是分散在组件中。以上是关于Angular 5 / Typescript - 如何将复杂的 json 对象转换为类的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Angular 5 中从 Typescript 调用 JavaScript 函数?
从 API 响应读取响应标头 - Angular 5 + TypeScript
从 Angular 2 Typescript 播放 HTML 5 视频