Angular2自动将JSON响应转换为类

时间:2018-03-15 11:05:20

标签: angular class typescript

我有这个词:

import { Address } from './address';
import { Contact } from './contact';

export class User {
  public $class = 'org.test.crm.participants.User';

  constructor(
    public id: string,
    public name: string,
    public surname: string,
    public jobTitle: string,
    public address: Address,
    public contacts: Contact[]
  ) {}
}

export class Address {

  public $class = 'org.test.crm.concepts.Address';
  public street: string;
  public city: string;
  public state: string;
  public country: string;
  public postCode: string;
  public timeZone: string;

  constructor(
    address: Address
  ) {
    this.street = address.street;
    this.city = address.city;
    this.state = address.state;
    this.country = address.country;
    this.postCode = address.postCode;
    this.timeZone = address.timeZone;
  }
}

export class Contact {

  public $class = 'org.test.crm.concepts.Contact';
  public email: string;
  public telephone: string;
  public mobile: string;

  constructor(contact: Contact) {
    this.email = contact.email;
    this.telephone = contact.telephone;
    this.mobile = contact.mobile;
  }
}

我有服务,在调用后返回JSON,如:

[  
   {  
      "$class":"org.test.crm.participants.User",
      "id":"USER_1",
      "name":"Vin",
      "surname":"Diesel",
      "jobTitle":"CEO",
      "address":{  
         "$class":"org.test.crm.concepts.Place",
         "street":"Some street",
         "city":"Some city",
         "postCode":"100 00",
         "state":"",
         "country":"CZE",
         "timeZone":"UTC"
      },
      "contacts":[  
         {  
            "$class":"org.test.crm.concepts.Contact",
            "email":"vin@diesel.com"
         }
      ],
      "systemInformation":{  
         "$class":"org.test.crm.concepts.SystemInformation",
         "created":"2018-03-14T11:53:52.773Z",
         "createdBy":"resource:org.hyperledger.composer.system.NetworkAdmin#admin",
         "lastModified":"2018-03-14T11:53:52.773Z",
         "lastModifiedBy":"resource:org.hyperledger.composer.system.NetworkAdmin#admin"
      }
   }
]

有没有简单的方法如何将此结果转换为用户数组?如何更改我的构造函数或其他东西以自动转换ajax的返回?现在我正在这样做:

this.users = <User[]> result;

但是不要将结果转换为User类,返回只是像以前一样的JSON数组...当我手动分配所有属性时,它的正确用户类...我可以自动执行此操作吗?

2 个答案:

答案 0 :(得分:0)

您可以映射数组并使用 Object.assign

this.users = result.map( user => Object.assign(new User(), user));

答案 1 :(得分:0)

this.users = <User[]> result;等于this.users = result;<User[]>注释只是告诉TypeScript编译器在编译时应该是result,并且它不会向运行时添加任何检查或转换。

  

类型断言是告诉编译器的一种方式“相信我,我知道我在做什么。”类型断言就像在其他语言中使用类型转换,但不执行特殊的数据检查或重组。它没有运行时影响,纯粹由编译器使用。 TypeScript假定您(程序员)已执行了您需要的任何特殊检查。

https://www.typescriptlang.org/docs/handbook/basic-types.html#type-assertions

您遇到的问题是反序列化问题。 由于您的初始数据是JSON字符串,因此在服务中调用reviver时可以使用JSON.parse(string, reviver)函数。 http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse

const getReviver = (classes: any[]) => {
  const classMap = classes.reduce((map, class) => {
    if(class.$class){
      map[class.$class] = class;
    }
    return map;
  }, {});

  const reviver = (key, value) => {
    if(typeof value === 'object' && value.$class && classMap[value.$class]) {
      return new classMap[value.$class](value);
    }
    return value;
  }

  return reviver;
}

例如

const reviver = getReviver([Address, Contact])
const revivedData = JSON.parse(string, reviver);