web-dev-qa-db-fra.com

Comment définir un objet imbriqué dans le modèle? (angular2/TypeScript)

Je me suis amusé avec Angular2 et espérais que quelqu'un pourrait donner quelques conseils sur la manière de réaliser cela;

Par exemple, si mon modèle ressemble actuellement à ceci pour un employé:

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

et je veux placer des jours/heure dans leur propre objet, comment cela pourrait-il être réalisé?

(i.e comme ..)

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

et alors la demande http obtenir resterait-elle comme ci-dessous?

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
             })
          }

Juste pour clarifier, je voudrais que ma requête get retourne quelque chose comme;

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

J'espère que quelqu'un peut aider! J'ai essayé de regarder autour de moi, mais je n'ai rien trouvé qui puisse aider.

5

Quelque chose comme ça 

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
    ){}
}

La requête get HTTP devrait rester la même, puis changer la façon dont vous créez une nouvelle instance d'employé

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

Personnellement, j’ai fait (pour le projet Ionic) quelque chose comme:

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

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

    availability = new Availability()
}

Donc, si j'utilise ces modèles dans un <form>, je reçois une structure vide de cette classe Employee.

Cela fonctionne également lorsque je déclare des variables telles que employeeObservable : Observable<Employee[]>; lorsque je demande par exemple à une base de données Firebase ... 

1
Ricky Levi

Quelques années plus tard, il existe une bibliothèque utile pour ce transformateur de classe.

Utiliser cette bibliothèque a été la plus simple: 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);
    }
}

Quelques choses ont changé:

  1. L'utilisation du décorateur @Type provient du module classe-transformateur. Cela vous permet de transformer des objets imbriqués. Voici la documentation: https://github.com/typestack/class-transformer#working-with-nested-objects
  2. Nous avons ajouté une constructor qui vous permet de créer des instances de ces classes et de leur transmettre des attributs de leurs propres types respectifs. Jetez un oeil à cet article Conversion de httpClient answer en objets modèle [Angular 6] , car il éclaire davantage ce qui se passe ici.

Ensuite, dans votre service, voici comment votre code change:

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 prendra la réponse JSON brute et la transformera en instances de votre classe Employee. Si vous console.log le résultat de getEmployees(), vous verrez qu'il renvoie un tableau d'employés ayant chacun un attribut appelé availability de type Disponibilité.

0
jetset