简体   繁体   English

将JSON解析为Angular app中的Typescript类

[英]Parse JSON to Typescript class in Angular app

I'm creating a app usign angular and typescript. 我正在创建一个应用程序使用角度和打字稿。 Everything is comming together nicely, but one issue bugs me. 一切都很好地融合在一起,但有一个问题让我感到困惑。

I define entity/model classes that i would like to pass around in the app, the data for the classes comes from JSON from $resource calls. 我定义了我想在应用程序中传递的实体/模型类,类的数据来自$ resource调用的JSON。

Here is an example of a model class: 以下是模型类的示例:

module app.domain {

    export interface IJob {
        id: number;
        jobTitle: string;
        jobDescription: string;
    }

    export class Job implements IJob {

       constructor(public id:number, public jobTitle: string, public jobDescription: string) {

       }
    }
}

I access my JSON resource through a service that returns the resource: 我通过返回资源的服务访问我的JSON资源:

namespace app.services {
    'use strict';

    interface IDataService {
        getJobResource(): angular.resource.IResourceClass<IJobResource>
    }

    interface IJobResource extends angular.resource.IResource<app.domain.IJob>{

    }

    export class DataService implements IDataService {

        static $inject: Array<string> = ['$log','$resource','ApiDataEndpoint'];
        constructor(
                    private $log: angular.ILogService,
                    private $resource: angular.resource.IResourceService,
                    private ApiDataEndpoint          
            ){}

        getJobResource(): angular.resource.IResourceClass<IJobResource>{
            return this.$resource(this.ApiDataEndpoint.url + 'job/:id',{});
        }
    }

    angular
        .module('app.services',[])
        .service('dataService', DataService);
}

This is where it goes wrong, when I cast the result of the resource call to Ijob typescript restrict me to call properties that don't match the names in the interface (as expected) but because this is still just JSON I'm unable to make method calls and if the properties en the IJob interface do not match the names in the JSON result the I get nothing. 这是它出错的地方,当我将资源调用的结果转换为Ijob typescript限制我调用与接口中的名称不匹配的属性(如预期的那样),但因为这仍然只是JSON我不能make方法调用,如果IJob接口的属性与JSON结果中的名称不匹配,我什么也得不到。

So, my questing is: What is the correct way to implement a service that calls a restfull endpoint that returns JSON and then returns an array of objects or a single object. 所以,我的任务是:实现调用restfull端点的服务的正确方法是什么,该服务返回JSON然后返回一个对象数组或一个对象。 The way should support that names on JSON and on the objects might not match. 这种方式应该支持JSON上的名称和对象可能不匹配。

You could make a class that has the functionality you need and gets a IJob object to work with. 您可以创建一个具有所需功能的类,并获取一个IJob对象。

module app.domain {

    export interface IJob {
        id: number;
        jobTitle: string;
        jobDescription: string;
    }

    export class Job {
       // keep the data received from the server private
       constructor(private jobData: IJob) {}

       // class methods
       public isIdGreaterThanTen(): boolean {
         return this.jobData.id > 0;
       }

       // expose the properties of the IJob interface via getters and setters
       public get id(): number { 
         return this.jobData.id;
       }

       public set id(id: number): void {
         this.jobData.id = id;
       }

       // so on for all properties if needed
       // ...

    }
}

In the service you can use the transformResponse functionality of $resource to create and return a new instance of the Job class instead of the object returned by the server. 在服务中,您可以使用$ resourcetransformResponse功能来创建和返回Job类的新实例,而不是服务器返回的对象。

namespace app.services {
    'use strict';

    interface IDataService {
        getJobResource(): angular.resource.IResourceClass<IJobResource>
    }

    // use the Job class instead of the interface
    interface IJobResource extends angular.resource.IResource<app.domain.Job>{

    }

    export class DataService implements IDataService {

        static $inject: Array<string> = ['$log','$resource','ApiDataEndpoint'];
        constructor(
                    private $log: angular.ILogService,
                    private $resource: angular.resource.IResourceService,
                    private ApiDataEndpoint          
            ){}

        getJobResource(): angular.resource.IResourceClass<IJobResource>{
            return this.$resource(this.ApiDataEndpoint.url + 'job/:id',{},
            {
              get: {
                method: 'GET',
                transformResponse: function(data: IJob) {
                  return new Job(data); // create a new instance of the Job class and return it
                }
              }
            });
        }
    }

    angular
        .module('app.services',[])
        .service('dataService', DataService);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM