如何在模型中定义嵌套对象? (angular2 /打字稿)

时间:2016-11-16 13:43:00

标签: angular typescript angular2-http

我正在玩Angular2,并希望有人可以就如何实现这一点提供一些建议;

例如,如果我的模型目前对于员工来说是这样的:

export class Employee {
    constructor(
        public firstName: string,
        public lastName: string,
        public email: string,
        public days: string,
        public hours: string, 
    ){}
}

我希望将天/小时放入他们自己的对象,怎么可能实现?

(即喜欢..)

public availability: {
        public days: string,
        public hours: string
},

然后http get请求保持不变如下所示?

getEmployees() {
      return this.http.get('...')
             .map((response: Response) => {
                 const data = response.json().obj;
                 let objs: any[] = [];

                 for(let i = 0; i < data.length; i++) {
                     let employee = new Employee(
                     data[i].firstName,
                     data[i].lastName, 
                     data[i].email, 
                     data[i].availability.days,
                     data[i].availability.hours
                     );

                     objs.push(employee)
                 }
                 return objs
             })
          }

为了澄清,我希望我的请求能够返回类似的内容;

var obj = {
    firstName: "test",
    lastName: "test",
    email: "test",
    availability: {
      days: "test",
      hours: "test"
    }
  }

希望有人可以帮忙!我试图环顾四周,但没有遇到任何有用的东西。

3 个答案:

答案 0 :(得分:11)

像这样的东西

export class Employee {
    constructor(
        public firstName: string,
        public lastName: string,
        public email: string,
        public availability: Availability // refer to type Availability  below
    ){}
}

export class Availability {
    constructor(
        public days: string,
        public hours: string
    ){}
}

Http get请求应保持不变,然后更改您创建新员工实例的方式

let employee = new Employee(
    data[i].firstName,
    data[i].lastName,
    data[i].email,
    new Availability(
          data[i].availability.days,
          data[i].availability.hours
    )
);

答案 1 :(得分:1)

我个人(为Ionic项目做过)

export class Availability {
    days: string  = "";
    hours: string = "";
}

export class Employee {
    firstName: string = "";
    lastName:  string = "";
    email:     string = "";

    availability = new Availability()
}

因此,如果我在<form>中使用这些模型,则会收到此Employee类的空结构。

当我查询Firebase数据库时声明employeeObservable : Observable<Employee[]>;之类的变量时,它也可以工作...

答案 2 :(得分:0)

对于几年后出现这种情况的人,有一个有用的库可以帮助您解决这个问题,称为class-transformer。

使用该库是最简单的:https://github.com/typestack/class-transformer

import { Type } from 'class-transformer';

export class Employee {
    firstName: string;
    email: string;
    days: string;
    hours: string;

    @Type(() => Availability)
    availablity: Availablity

    constructor(args: Employee) {
      Object.assign(this, args);
    }
}

export class Availability {
    days: string;
    hours: string;

    constructor(args: Availability) {
      Object.assign(this, args);
    }
}

一些变化:

  1. @Type装饰器的使用来自class-transformer模块。这使您可以转换嵌套对象。以下是文档:https://github.com/typestack/class-transformer#working-with-nested-objects
  2. 我们添加了constructor,可让您创建这些类的实例,并将属性传递给它们各自的类型。看看这篇帖子Converting httpClient answer to model objects [Angular 6],因为它可以使您更加了解这里发生的事情。

然后在您的服务中,这就是代码的更改方式:

import { plainToClass } from 'class-transformer';
import { Employee } from './Employee'

getEmployees() {
  return this.http.get('...')
    .map((response: Response) => plainToClass(Employee, response.json().obj as Employee[]))

plainToClass将获取原始的JSON响应并将其转换为Employee类的实例。如果您用console.logout退出getEmployees()的结果,您会看到它返回一个员工数组,每个员工数组都有一个称为availability的类型的属性。