Comment utiliser une valeur d’énumération de typecript dans une instruction Angular2 ngSwitch

L’énumération Typescript semble correspondre naturellement à la directive ngSwitch d’Angular2. Mais quand j’essaie d’utiliser un enum dans le template de mon composant, j’obtiens “Impossible de lire la propriété ‘xxx’ de undefined in …”. Comment puis-je utiliser des valeurs enum dans mon modèle de composant?

Veuillez noter que ceci est différent de la façon de créer des options de sélection HTML en fonction de TOUTES les valeurs d’un enum (ngFor). Cette question concerne ngSwitch en fonction d’une valeur particulière d’un enum. Bien que la même approche de création d’une référence interne à la classe apparaisse.

Vous pouvez créer une référence à l’énumération dans votre classe de composant (j’ai simplement modifié le caractère initial pour qu’il soit en minuscule), puis utiliser cette référence à partir du modèle ( plunker ):

import {Component} from 'angular2/core'; enum CellType {Text, Placeholder} class Cell { constructor(public text: ssortingng, public type: CellType) {} } @Component({ selector: 'my-app', template: ` 
{{cell.text}}
Placeholder
`, }) export default class AppComponent { // Store a reference to the enum cellType = CellType; public cell: Cell; constructor() { this.cell = new Cell("Hello", CellType.Text) } setType(type: CellType) { this.cell.type = type; } }

Vous pouvez créer un décorateur personnalisé à append à votre composant pour le rendre conscient des énumérations.

myenum.enum.ts:

 export enum MyEnum { FirstValue, SecondValue } 

myenumaware.decorator.ts

 import { MyEnum } from './myenum.enum'; export function MyEnumAware(constructor: Function) { constructor.prototype.MyEnum = MyEnum; } 

enum-aware.component.ts

 import { Component } from '@angular2/core'; import { MyEnum } from './myenum.enum'; import { MyEnumAware } from './myenumaware.decorator'; @Component({ selector: 'enum-aware', template: ` 
First Value
Second Value
`, }) @MyEnumAware // <---------------!!! export default class EnumAwareComponent { myEnumValue: MyEnum = MyEnum.FirstValue; toggleValue() { this.myEnumValue = this.myEnumValue === MyEnum.FirstValue ? MyEnum.SecondValue : MyEnum.FirstValue; } }

Angular4 – Utiliser Enum dans un modèle HTML ngSwitch / ngSwitchCase

Solution ici: https://stackoverflow.com/a/42464835/802196

crédit: @snorkpete

Dans votre composant, vous avez

 enum MyEnum{ First, Second } 

Ensuite, dans votre composant, vous introduisez le type Enum via un membre ‘MyEnum’ et créez un autre membre pour votre variable enum ‘myEnumVar’:

 export class MyComponent{ MyEnum = MyEnum; myEnumVar:MyEnum = MyEnum.Second ... } 

Vous pouvez maintenant utiliser myEnumVar et MyEnum dans votre modèle .html. Par exemple, utiliser Enums dans ngSwitch:

 
MyEnumVar {{myEnumVar}} is not handled.

à partir de rc.6 / final

 export enum AdnetNetworkPropSelector { CONTENT, PACKAGE, RESOURCE } 
export class AdnetNetwork { private adnetNetworkPropSelector = AdnetNetworkPropSelector; private propSelector = AdnetNetworkPropSelector.CONTENT; }

C’est simple et fonctionne comme un charme 🙂 déclarez simplement votre enum comme ceci et vous pouvez l’utiliser sur le modèle HTML

  statusEnum: typeof SatusEnum = SatusEnum; 

Comme alternative au décorateur de @Eric Lease, qui ne fonctionne malheureusement pas avec les --aot (et donc --prod ), j’ai eu recours à un service qui expose toutes les énumérations de mes applications. Juste besoin d’injecter publiquement cela dans chaque composant qui le nécessite, sous un nom facile, après quoi vous pouvez accéder aux énumérations dans vos vues. Par exemple:

Un service

 import { Injectable } from '@angular/core'; import { MyEnumType } from './app.enums'; @Injectable() export class EnumsService { MyEnumType = MyEnumType; // ... } 

N’oubliez pas de l’inclure dans la liste des fournisseurs de votre module.

Classe de composant

 export class MyComponent { constructor(public enums: EnumsService) {} @Input() public someProperty: MyEnumType; // ... } 

Composant html

 
Some property has some value!

Si vous utilisez l’approche ‘typetable reference’ (à partir de @Carl G) et que vous utilisez plusieurs tables de types, vous pouvez envisager cette méthode:

 export default class AppComponent { // Store a reference to the enums (must be public for --AOT to work) public TT = { CellType: CellType, CatType: CatType, DogType: DogType }; ... dog = DogType.GoldenResortingever; 

Accédez ensuite dans votre fichier HTML avec

 {{ TT.DogType[dog] }} => "GoldenResortingever" 

Je suis favorable à cette approche car elle indique clairement que vous faites référence à une typable et évite également une pollution inutile de votre fichier de composants.

Vous pouvez également placer un TT global quelque part et y append des énumérations au besoin (si vous le souhaitez, vous pouvez également créer un service comme indiqué par la réponse de @VincentSels). Si vous avez beaucoup de types de caractères, cela peut devenir encombrant.

Aussi, vous les renommez toujours dans votre déclaration pour obtenir un nom plus court.

Commencez par considérer ‘Est-ce que je veux vraiment faire ça?’

Je n’ai aucun problème à faire référence aux énumérations directement en HTML, mais dans certains cas, il existe des alternatives plus propres qui ne perdent pas leur sécurité. Par exemple, si vous choisissez l’approche indiquée dans mon autre réponse, vous avez peut-être déclaré TT dans votre composant comme suit:

 public TT = { // Enum defines (Horizontal | Vertical) FeatureBoxResponsiveLayout: FeatureBoxResponsiveLayout } 

Pour afficher une mise en page différente dans votre code HTML, vous devriez avoir un *ngIf pour chaque type de mise en page et vous pouvez vous référer directement à l’énumération dans le code HTML de votre composant:

 *ngIf="(featureBoxResponsiveService.layout | async) == TT.FeatureBoxResponsiveLayout.Horizontal" 

Cet exemple utilise un service pour obtenir la disposition actuelle, l’exécute via le canal asynchrone, puis le compare à notre valeur enum. C’est assez verbeux, alambiqué et pas très amusant à regarder. Il expose également le nom de l’énumération, qui peut être trop verbeux.

Alternative, qui conserve la sécurité de type du HTML

Vous pouvez également procéder comme suit et déclarer une fonction plus lisible dans le fichier .ts de votre composant:

 *ngIf="isResponsiveLayout('Horizontal')" 

Beaucoup plus propre! Mais que faire si quelqu’un tape 'Horziontal' par erreur? Toute la raison pour laquelle vous vouliez utiliser un enum dans le code HTML était d’être type

Nous pouvons toujours réaliser cela avec keyof et certains types de magie. C’est la définition de la fonction:

 isResponsiveLayout(value: keyof typeof FeatureBoxResponsiveLayout) { return FeatureBoxResponsiveLayout[value] == this.featureBoxResponsiveService.layout.value; } 

Notez l’utilisation de FeatureBoxResponsiveLayout[ssortingng] qui convertit la valeur de chaîne transmise à la valeur numérique de l’énumération.

Cela donnera un message d’erreur avec une compilation AOT si vous utilisez une valeur non valide.

L’argument de type ‘”H4orizontal”‘ n’est pas assignable au paramètre de type ‘”Vertical” | “Horizontal”

Actuellement, VSCode n’est pas assez intelligent pour souligner H4orizontal dans l’éditeur HTML, mais vous recevrez l’avertissement au moment de la compilation (avec –prod build ou –aot switch). Cela peut également être amélioré dans une future mise à jour.