for enum typescript angular

for - export enum typescript



Cómo usar un valor de enumeración mecanografiado en una instrucción Angular2 ngSwitch (9)

La enumeración de Typecript parece una coincidencia natural con la directiva ngSwitch de Angular2. Pero cuando trato de usar una enumeración en la plantilla de mi componente, aparece "No se puede leer la propiedad ''xxx'' de undefined en ...". ¿Cómo puedo usar valores de enumeración en mi plantilla de componente?

Tenga en cuenta que esto es diferente de cómo crear opciones de selección html basadas en TODOS los valores de una enumeración (ngFor). Esta pregunta es sobre ngSwitch basado en un valor particular de una enumeración. Aunque aparece el mismo enfoque de crear una referencia interna de clase a la enumeración.


Comience por considerar ''¿ Realmente quiero hacer esto?''

No tengo problemas para referirme a las enumeraciones directamente en HTML, pero en algunos casos hay alternativas más limpias que no pierden la seguridad de escritura. Por ejemplo, si elige el enfoque que se muestra en mi otra respuesta, puede haber declarado TT en su componente algo como esto:

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

Para mostrar un diseño diferente en su HTML, tendría un *ngIf para cada tipo de diseño, y podría referirse directamente a la enumeración en el HTML de su componente:

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

Este ejemplo utiliza un servicio para obtener el diseño actual, lo ejecuta a través de la tubería asíncrona y luego lo compara con nuestro valor de enumeración. Es bastante detallado, complicado y no es muy divertido de ver. También expone el nombre de la enumeración, que en sí mismo puede ser demasiado detallado.

Alternativa, que conserva la seguridad de tipo del HTML

Alternativamente, puede hacer lo siguiente y declarar una función más legible en el archivo .ts de su componente:

*ngIf="isResponsiveLayout(''Horizontal'')"

Mucho más limpio! Pero, ¿qué ''Horziontal'' si alguien escribe ''Horziontal'' por error? Toda la razón por la que querías usar una enumeración en el HTML era para ser seguro de texto, ¿verdad?

Todavía podemos lograr eso con keyof y algo de magia mecanografiada. Esta es la definición de la función:

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

Tenga en cuenta el uso de FeatureBoxResponsiveLayout[string] que converts el valor de cadena pasado al valor numérico de la enumeración.

Esto dará un mensaje de error con una compilación AOT si usa un valor no válido.

El argumento del tipo ''"H4orizontal"'' no se puede asignar al parámetro del tipo ''"Vertical" | "Horizontal"

Actualmente, VSCode no es lo suficientemente inteligente como para subrayar H4orizontal en el editor HTML, pero recibirá la advertencia en el momento de la compilación (con --prod build o --aot switch). Esto también se puede mejorar en una futura actualización.


Angular4: uso de Enum en la plantilla HTML ngSwitch / ngSwitchCase

Solución aquí: https://.com/a/42464835/802196

crédito: @snorkpete

En tu componente, tienes

enum MyEnum{ First, Second }

Luego, en su componente, introduce el tipo Enum a través de un miembro ''MyEnum'' y crea otro miembro para su variable enum ''myEnumVar'':

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

Ahora puede usar myEnumVar y MyEnum en su plantilla .html. Por ejemplo, usando Enums en ngSwitch:

<div [ngSwitch]="myEnumVar"> <div *ngSwitchCase="MyEnum.First"><app-first-component></app-first-component></div> <div *ngSwitchCase="MyEnum.Second"><app-second-component></app-second-component></div> <div *ngSwitchDefault>MyEnumVar {{myEnumVar}} is not handled.</div> </div>


Como alternativa al decorador de @Eric Lease, que desafortunadamente no funciona usando las --aot (y por lo tanto --prod ), recurrí al uso de un servicio que expone todas las enumeraciones de mi aplicación. Solo necesita inyectarlo públicamente en cada componente que lo requiera, con un nombre fácil, después del cual puede acceder a las enumeraciones en sus vistas. P.ej:

Servicio

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

No olvide incluirlo en la lista de proveedores de su módulo.

Clase de componentes

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

Componente html

<div *ngIf="someProperty === enums.MyEnumType.SomeValue">Match!</div>


Esto es simple y funciona como un encanto :) simplemente declara tu enumeración como esta y puedes usarla en la plantilla HTML

statusEnum: typeof SatusEnum = SatusEnum;


Mi componente usó un objeto myClassObject del tipo MyClass , que estaba usando MyEnum . Esto condujo al mismo problema descrito anteriormente. Lo resolvió haciendo:

export enum MyEnum { Option1, Option2, Option3 } export class MyClass { myEnum: typeof MyEnum; myEnumField: MyEnum; someOtherField: string; }

y luego usar esto en la plantilla como

<div [ngSwitch]="myClassObject.myEnumField"> <div *ngSwitchCase="myClassObject.myEnum.Option1"> Do something for Option1 </div> <div *ngSwitchCase="myClassObject.myEnum.Option2"> Do something for Option2 </div> <div *ngSwitchCase="myClassObject.myEnum.Option3"> Do something for Opiton3 </div> </div>


Puede crear un decorador personalizado para agregar a su componente para que tenga conocimiento de las enumeraciones.

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: ` <div [ngSwitch]="myEnumValue"> <div *ngSwitchCase="MyEnum.FirstValue"> First Value </div> <div *ngSwitchCase="MyEnum.SecondValue"> Second Value </div> </div> <button (click)="toggleValue()">Toggle Value</button> `, }) @MyEnumAware // <---------------!!! export default class EnumAwareComponent { myEnumValue: MyEnum = MyEnum.FirstValue; toggleValue() { this.myEnumValue = this.myEnumValue === MyEnum.FirstValue ? MyEnum.SecondValue : MyEnum.FirstValue; } }


Puede crear una referencia a la enumeración en su clase de componente (acabo de cambiar el carácter inicial a minúsculas) y luego usar esa referencia de la plantilla ( plunker ):

import {Component} from ''angular2/core''; enum CellType {Text, Placeholder} class Cell { constructor(public text: string, public type: CellType) {} } @Component({ selector: ''my-app'', template: ` <div [ngSwitch]="cell.type"> <div *ngSwitchCase="cellType.Text"> {{cell.text}} </div> <div *ngSwitchCase="cellType.Placeholder"> Placeholder </div> </div> <button (click)="setType(cellType.Text)">Text</button> <button (click)="setType(cellType.Placeholder)">Placeholder</button> `, }) 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; } }


Si utiliza el enfoque de ''referencia de tipografía'' (de @Carl G) y está utilizando múltiples tablas de tipos, puede considerar de esta manera:

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.GoldenRetriever;

Luego acceda a su archivo html con

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

Estoy a favor de este enfoque, ya que deja en claro que te estás refiriendo a una tabla tipográfica y también evita la contaminación innecesaria de tu archivo componente.

También puede colocar un TT global en algún lugar y agregar enumeraciones según sea necesario (si lo desea, también puede hacer un servicio como se muestra en la respuesta @VincentSels). Si tiene muchos tipos de letra, esto puede volverse engorroso.

También siempre los renombra en su declaración para obtener un nombre más corto.


a partir de rc.6 / final

...

export enum AdnetNetworkPropSelector { CONTENT, PACKAGE, RESOURCE } <div style="height: 100%"> <div [ngSwitch]="propSelector"> <div *ngSwitchCase="adnetNetworkPropSelector.CONTENT"> <AdnetNetworkPackageContentProps [setAdnetContentModels]="adnetNetworkPackageContent.selectedAdnetContentModel"> </AdnetNetworkPackageContentProps> </div> <div *ngSwitchCase="adnetNetworkPropSelector.PACKAGE"> </div> </div> </div> export class AdnetNetwork { private adnetNetworkPropSelector = AdnetNetworkPropSelector; private propSelector = AdnetNetworkPropSelector.CONTENT; }