最佳做法/仅可能性。 “通过构造函数将Json转换为Javascript / Typescript对象”

时间:2019-05-14 19:07:23

标签: javascript json typescript object constructor

我开始使用angular /打字稿进行开发,并为.NET Core API创建了服务,我想知道从我的服务中获得干净可靠的对象的最佳方法是什么。

我有一个.NET CORE REST API,它返回由下面的类定义表示的json结果。

服务: demoservice.getDemo().subscribe((val) => new Demo(val));

演示类是以下代码:

export class Demo  {
    public id : number;
    public name : string;
    public subDemo: SubDemo;

    constructor(demo: Demo) {
      this.id = demo.id;
      this.name = demo.name;
      this.subDemo = new SubDemo(demo.subDemo);
    }
}

export class SubDemo {
    public demoList : ListDemo[]

    constructor(subDemo: SubDemo) {
        this.demoList = new Array<ListDemo>();
        subDemo.demoList.forEach(dl => {
            this.demoList.push(new ListDemo(dl))
        });
    }
}

export class ListDemo {
    constructor(listdemo : ListDemo) {
        this.birthday = listdemo.birthday;
        this.smoker = listdemo.smoker;    
    }

    get birthDayFormatted() : Date {
        return new Date(this.birthday);
    }

    public birthday : string;
    public smoker : boolean;
}

这是创建对象的最佳方法(完全实现所有构造函数)。请注意,我喜欢使用ListDemo类的“ getter”功能。

没有更好的方法吗?我刚找到一些Object.clone / Object.assign / Object.create。

但是这些解决方案都不是全面的...

我真的对您的经历感兴趣。

2 个答案:

答案 0 :(得分:2)

由于您使用的是更好和最好的,所以我会回答我可能不想要的意见。 免责声明:我不是专家,这个答案是基于观点的,随时可以忽略。

不要这样做。您的服务器在其域中有一组对象,可能是某种问题解决或数据存储域。

您的客户端在其域中具有一组对象,通常专注于向用户呈现数据并允许用户理解和操纵数据。

这两个域都可能具有相同名称或基于相同现实世界概念的对象。让人觉得它们是具有相同对象的同一个域可能很诱人。他们不是。如果它们相同,那么您将不会编写客户端和服务器,而是会编写两个相同的东西。两者应与纯数据对象通信。在TS中,这意味着您只应为从服务器接收的对象创建一个接口,而不是一个类。

相反,请重新开始。根据您想在API中显示的内容创建一个新域。如果您从顶部(UI)到底部(访问服务)设计API,则可能会发现对象之间没有一对一的映射。在这种情况下,您可能可以偶尔进行分配/合并(请参阅下文),但我个人从未发现有理由做比您上面发布的内容更多的事情。

如果您坚持下去,可能会遇到从基础object到数据所代表的类reassign the prototype的JSON文字that is a contentious topic and potential performance pitfall.的选项。最好的选择可能是像Lodash的merge这样进行递归/深度分配。

答案 1 :(得分:1)

只使用接口而不是类。

export interface Demo  {
  id: number;
  name: string;
  subDemo: SubDemo;
}

export interface SubDemo {
  demoList: ListDemo[];
}

export interface ListDemo {
    birthday: string;
    smoker: boolean;
}

并且您的api应该返回相同的形状,您应该可以使用

getDemo(): Observable<Demo> {
  return this.http.get<Demo>('url');
}

在您的服务和组件中将其分配给属性

demo$ = this.service.getDemo();

,然后将可观察对象与模板中的异步管道一起使用。

<ng-container *ngIf="demo$ | async as demo">
  {{ demo | json }}
</ng-container>

操作数据越少越好。我有一个VS插件,可让您将C#类粘贴到TS文件中,并将其即时转换为TypeScript接口。