2017-06-11 9 views
0

Je voudrais que mes données javascript est comme ceci:signature index tapuscrit accesseurs

"dogs": { 
    "ada": { 
     age: 7, 
     breed: poodle 
    }, 
    "levin": { 
     age: 5, 
     breed: shitzu 
    }, 
    ... 
} 

Lorsque le nom est une clé d'objet. J'ai cette classe dactylographiée:

export class Dog { 
    [dogName: string]: DogDetails; 
} 

La seule façon que je pouvais voir que je pouvais résumer les méthodes pour créer accesssors est en ajoutant ces méthodes statiques pour Dog:

public static getDogName(dog: Dog): string { 
    return Object.keys(dog).toString(); 
    } 

    public static getDogDetails(dog: Dog): DogDetails { 
    return dog[Dog.getDogName(dog)]; 
    } 

Ce qui est assez horrible. Une raison en est que l'accès statique est nécessaire:

Dog.getDogName(dog) // this is how it must be done 

Et semble donc contraire à la façon dont cela devrait être écrit, qui serait:

dog.getName(); // this unfortunately can't be done 

La situation serait beaucoup plus agréable s'il y avait un moyen pour accéder à la valeur de la signature d'index. Cependant, je n'ai trouvé aucun moyen d'y parvenir. Y a-t-il un moyen ou existe-t-il un meilleur moyen d'écrire ce cours?

Notez que cela est impossible avec des classes en utilisant des signatures d'index:

public getName(): string { // this won't work 
    Object.keys(this).toString(); 
} 

Comme il se plaint Property 'getName' of type '() => string' is not assignable to string index type 'DogDetails'


mise à jour après la réponse de @amiramw et commentaires conversation

Le composant angulaire où ceci est utilisé est:

<ion-list *ngFor="let dog of dogs"> 
    <ion-item> 
     <ion-avatar item-start> 
     <img src="assets/img/dog.jpg"/> 
     </ion-avatar> 
     <h4>{{Dog.getName(dog)}}</h4> 
     <p>{{Dog.getDogDetails(dog).breed}}</p> 
    </ion-item> 
    </ion-list> 

Après les commentaires, il semble que je vais devoir écrire:

<ion-list *ngFor="let dogName of getDogNames()"> 
    <ion-item> 
     <ion-avatar item-start> 
     <img src="assets/img/dog.jpg"/> 
     </ion-avatar> 
     <h4>{{dogName}}</h4> 
     <p>{{getDogDetails(dogName).breed}}</p> 
    </ion-item> 
    </ion-list> 

getDogNames() est:

public getDogNames(): string[] { 
    if (this.dogs) { 
     return Object.keys(this.dogs); 
    } else { 
     return new Array<string>(); 
    } 
    } 

Et getDogDetails() est:

public getDogDetails(name: string): DogDetails { 
    return this.dogs[name]; 
    } 

qui fonctionne, mais Ce n'est pas ce que je cherchais. Je vais donner @amiramw crédit pour la suggestion d'une solution à mon problème global.

Cependant j'apprécierais beaucoup savoir s'il y a un moyen d'obtenir la valeur de signature d'index de type?

Répondre

0

Vous pouvez créer une interface pour les données de chaque chien et définir une carte de chaîne à cette interface. L'interface peut être nommée (pour réutilisation) ou anonyme:

enum Breed { 
    poodle, 
    shitzu 
} 
let dogs : { [key:string]: {age: number, breed: Breed} } = { 
    "ada": { 
     age: 7, 
     breed: Breed.poodle 
    }, 
    "levin": { 
     age: 5, 
     breed: Breed.shitzu 
    } 
}; 
+0

Comment obtenez-vous le nom? par exemple. "ada" – HankCa

+0

Vous pouvez obtenir la liste des chiens en appelant 'Object.keys (chiens)' et ensuite vous avez les noms et vous pouvez accéder aux données de chaque chien en 'faisant dogs [dogName]'. L'autre option consiste à maintenir la liste des chiens dans un tableau et à ajouter la propriété 'name' à l'interface. – amiramw

+0

Ok, je vois votre approche.Je ne pense pas que votre code dactylographié soit essentiellement différent de ce que j'ai, c'est juste votre approche d'accès aux données. C'est peut-être comme cela que je dois le faire, mais c'est contraire à la façon dont je pense que cela devrait être fait et différent des cas de manuels. Je vais mettre à jour ma question pour me qualifier avec le code angulaire utilisé pour parcourir ces données. Merci pour vos efforts. – HankCa