2016-12-31 2 views
0

J'ai ces classes TypeScript dans le même fichier .ts car il y a des dépendances d'importation. Je vous serais reconnaissant si quelqu'un pourrait me aider à Refactor le code pour que je puisse supprimer la référence circulaire des importations:Est-il possible de refactoriser cette dépendance circulaire dans TypeScript afin que des fichiers TypeScript distincts soient possibles?

Le premier est le GenericModel abstrait:

export abstract class GenericModel { 
    nodeClass: string; 
    id: string = "0"; 

    static fromJson(json: any): GenericModel { 
     if (json.nodeClass === "Entity") { 
      return EntityModel.fromJson(json); 
     } 
     else if(json.nodeClass === "User") { 
      return UserModel.fromJson(json); 
     } 
     return null; 
    } 
} 

Les deux autres classes sont EntityModel (énumérés ci-dessous) et UserModel:

export class EntityModel extends GenericModel { 
    nodeClass: string = "Entity"; 
    alias: string; 
    description: string; 

    constructor(public text: string, public id: string, public uuid: string, alias: string, public rand:string = "") { 
     //[...] 
    } 

    //instance methods 
    //[...] 

    public static fromJson(json: any): EntityModel { 
     var entity = new EntityModel(json.text, json.id, json.uuid, json.alias, json.rand); 
     entity.description = json.description; 

     if (json.types) { 
      for (let type of json.types) { 
       let objectifiedType: EntityModel = EntityModel.fromJson(type); 
       entity.types.push(objectifiedType); 
      } 
     } 
     if (json.innerEntities){ 
      for (let innerEntity of json.innerEntities) { 
       let objectifiedInnerEntity: EntityModel = EntityModel.fromJson(innerEntity); 
       entity.innerEntities.push(innerEntity); 
      } 
     } 
     return entity; 
    } 
} 

Ce que je fais ici est de désérialisation JSON en utilisant une hiérarchie d'appels statiques fromJson() basés sur nodeClass.

Il est évident que si GenericModel était dans un fichier séparé, il aurait besoin d'importer EntityModel et UserModel tandis que les deux autres si elles étaient dans un fichier séparé dont ils auraient besoin d'importer GenericModel.

GenericModel --- has to import --> EntityModel, UserModel

EntityModel --- has to import --> GenericModel

UserModel --- has to import --> GenericModel

Je me demande s'il y a un moyen de factoriser le code il fait ce qu'il fait maintenant, mais les classes sont également dans les fichiers .ts séparés.

Merci!

Répondre

2

L'astuce ici est d'isoler les dépendances circulaires dans leur propre module. Je voudrais extraire toutes les méthodes fromJson dans un seul nouveau module. Ensuite, je voudrais convertir fromJson en une classe appelée quelque chose comme ModelFactory, car cela ressemble plus à un modèle d'usine. Ainsi, le résultat final ressemblerait à quelque chose comme ceci:

export class ModelFactory { 
    // maybe add a constructor for some configuration data, maybe not 

    create(json: any) { 
    ... 
    } 
} 

Maintenant, je vois que vous tapez l'objet json comme any. Cela semble être un peu large quand vous semblez connaître au moins quelques propriétés sur le type. Je vais essayer de créer une interface pour l'objet JSON, comme ceci:

export interface ModelJson { // find a better name 
    text?: string; 
    id?: number; 
    uuid?: UUID; 
    alias?: string; 
    rand?: number; 
    ... 
} 

type UUID = number; 

Ceci est une façon plus typescripty de faire les choses.

+0

Merci! J'ai eu le sentiment que je devrais ajouter une nouvelle classe comme l'usine que vous avez suggérée! Merci pour la pointe de l'interface/json :) Btw qu'est-ce que '' 'type UUID = nombre;' '' à la fin? Bonne année! –

+1

C'est juste un alias de type. Quand vous avez quelque chose comme un UID qui se trouve être un nombre, mais vraiment c'est juste un détail technique et il a sa propre sémantique, vous utilisez souvent un alias de type. Cela garantit que vous ne pouvez utiliser que des UID où vous le souhaitez et vous ne passerez pas accidentellement un numéro vanille. –

+0

pour moi le '' 'uuid''' est une chaîne si! Puis-je encore faire: '' 'type UUID = chaîne;' '' '? Merci –