2016-01-19 12 views
6

Sto creando un'app usign angolare e dattiloscritta. Tutto va bene insieme, ma un problema mi infastidisce.Analizza la classe da JSON a Typescript nell'app angolare

Definisco le classi entità/modello che vorrei passare in giro nell'app, i dati per le classi provengono da JSON dalle chiamate $ risorse.

Ecco un esempio di una classe del modello:

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

     } 
    } 
} 

accedo al mio risorsa JSON attraverso un servizio che restituisce la risorsa:

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

Questo è dove le cose vanno male, quando ho lanciato il risultato della chiamata di risorsa al dattiloscritto di Ijob mi limita a chiamare le proprietà che non corrispondono ai nomi nell'interfaccia (come previsto) ma poiché questo è ancora solo JSON, non sono in grado di effettuare chiamate di metodo e se le proprietà sono nell'IJob l'interfaccia non corrisponde ai nomi nel risultato JSON del ge ge niente

Quindi, la mia ricerca è: Qual è il modo corretto di implementare un servizio che chiama un endpoint restfull che restituisce JSON e quindi restituisce una matrice di oggetti o un singolo oggetto. Il modo in cui dovrebbero supportare i nomi su JSON e sugli oggetti potrebbe non corrispondere.

+0

Si potrebbe fare una classe decoratrice che prende l'interfaccia come uno degli argomenti del costruttore. Quindi sarai in grado di fare un nuovo lavoro (dati). – toskv

+0

@toskv interessante, potresti approfondire questa risposta, magari mostrare un piccolo esempio? – iCediCe

+0

Ho aggiunto la risposta, spero che questo si adatti al tuo problema. :) – toskv

risposta

2

È possibile creare una classe con le funzionalità necessarie e ottenere un oggetto IJob con cui lavorare.

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 
     // ... 

    } 
} 

Nel servizio è possibile utilizzare il transformResponse funzionalità del $ risorsa per creare e restituire una nuova istanza della classe lavoro anziché l'oggetto restituito dal server.

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); 
} 
+0

Questo sembra molto interessante. Lo proverò domani. – iCediCe