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.
typescript
angular
Carl G
fuente
fuente
Respuestas:
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 ):
fuente
Puede crear un decorador personalizado para agregar a su componente para que tenga conocimiento de las enumeraciones.
myenum.enum.ts:
myenumaware.decorator.ts
enum-aware.component.ts
fuente
MyEnumAware()
, dondeEnumAwareComponent
se pasa la instancia, y tiene una propiedadMyEnum
, agregada a su prototipo. El valor de la propiedad se establece en la enumeración en sí. Este método hace lo mismo que la respuesta aceptada. Simplemente aprovecha el azúcar sintáctico propuesto para decoradores y permitido en TypeScript. Cuando usas Angular, estás usando la sintaxis del decorador desde el principio. Eso es lo queComponent
es , una extensión de una clase vacía con la que las clases centrales de Angular saben cómo interactuar.ERROR in ng:///.../whatever.component.html (13,3): Property 'MyEnum' does not exist on type 'EnumAwareComponent'
. Esto tiene sentido, porque la propiedad que agrega el decorador nunca se declara, dejando al compilador de mecanografiado ignorante de su existencia.--prod
compilación (Ionic 3 / Angular 4 / Typecript 2.4.2) ya no funciona. Me sale el error"TypeError: Cannot read property 'FirstValue' of undefined"
. Estoy usando una enumeración numérica estándar. Funciona bien con AoT pero no con--prod
. Funciona si lo cambio a usar enteros en el HTML, pero ese no es el punto. ¿Algunas ideas?Esto es simple y funciona como un encanto :) simplemente declara tu enumeración de esta manera y puedes usarla en la plantilla HTML
fuente
StatusEnum
se define en una de las.ts
clases. En el componente angular que lo importa, enlácelo a una propiedad del componente (aquístatusEnum
) y las propiedades del componente son accesibles desde la plantilla.Angular4: uso de Enum en la plantilla HTML ngSwitch / ngSwitchCase
Solución aquí: https://stackoverflow.com/a/42464835/802196
crédito: @snorkpete
En tu componente, tienes
Luego, en su componente, introduce el tipo Enum a través de un miembro 'MyEnum' y crea otro miembro para su variable enum 'myEnumVar':
Ahora puede usar myEnumVar y MyEnum en su plantilla .html. Por ejemplo, usando Enums en ngSwitch:
fuente
a partir de rc.6 / final
...
fuente
Como alternativa al decorador de @Eric Lease, que desafortunadamente no funciona usando
--aot
(y por lo tanto--prod
) compilaciones, 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
No olvide incluirlo en la lista de proveedores de su módulo.
Clase de componentes
Componente html
fuente
Comience por considerar '¿ Realmente quiero hacer esto?'
No tengo ningún problema 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:
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: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í misma puede ser demasiado verbosa.
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:
Mucho más limpio! Pero, ¿qué pasa 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.Aún podemos lograr eso con keyof y algo de magia mecanografiada. Esta es la definición de la función:
Tenga en cuenta el uso de
FeatureBoxResponsiveLayout[string]
que convierte el valor de cadena pasado en el 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.
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 puede mejorarse en una futura actualización.fuente
html
pero veo tu punto y comencé a usarlo; hace el trabajo, como en los viejos tiempos, cuando compila! :)Mi componente usaba un objeto
myClassObject
de tipoMyClass
, que estaba usandoMyEnum
. Esto condujo al mismo problema descrito anteriormente. Lo resolvió haciendo:y luego usar esto en la plantilla como
fuente
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:
Luego acceda a su archivo html con
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 puedes poner un global
TT
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.
fuente