L'énumération Typescript semble une correspondance naturelle avec la directive ngSwitch d'Angular2. Mais quand j'essaye d'utiliser une énumération dans le modèle de mon composant, j'obtiens "Impossible de lire la propriété 'xxx' de undefined in ...". Comment puis-je utiliser des valeurs d'énumération dans mon modèle de composant?
Veuillez noter que cela est différent de la façon de créer des options de sélection html basées sur TOUTES les valeurs d'une énumération (ngFor). Cette question concerne ngSwitch basée sur une valeur particulière d'une énumération. Bien que la même approche de création d'une référence interne à la classe à l'énumération apparaisse.
typescript
angular
Carl G
la source
la source
Réponses:
Vous pouvez créer une référence à l'énumération dans votre classe de composant (je viens de changer le caractère initial en minuscules), puis utiliser cette référence à partir du modèle ( plunker ):
la source
Vous pouvez créer un décorateur personnalisé à ajouter à votre composant pour lui faire prendre conscience des énumérations.
myenum.enum.ts:
myenumaware.decorator.ts
enum-aware.component.ts
la source
MyEnumAware()
, où l'EnumAwareComponent
instance est passée, et a une propriété ,,MyEnum
ajoutée à son prototype. La valeur de la propriété est définie par l'énumération elle-même. Cette méthode fait la même chose que la réponse acceptée. Il profite simplement du sucre syntaxique proposé pour les décorateurs et autorisé dans TypeScript. Lorsque vous utilisez Angular, vous utilisez la syntaxe du décorateur dès le départ. C'est ce qu'unComponent
est une extension d'une classe vide que les classes de base de Angulaire savent comment interagir avec.ERROR in ng:///.../whatever.component.html (13,3): Property 'MyEnum' does not exist on type 'EnumAwareComponent'
. Cela a du sens, car la propriété ajoutée par le décorateur n'est jamais déclarée, laissant le compilateur dactylographié inconscient de son existence.--prod
compilation (Ionic 3 / Angular 4 / Typescript 2.4.2), cela ne fonctionne plus. J'obtiens l'erreur"TypeError: Cannot read property 'FirstValue' of undefined"
. J'utilise une énumération numérique standard. Cela fonctionne bien avec AoT mais pas avec--prod
. Cela fonctionne si je le change en utilisant des entiers dans le HTML, mais ce n'est pas le point. Des idées?C'est simple et fonctionne comme un charme :) déclarez simplement votre énumération comme ceci et vous pouvez l'utiliser sur un modèle HTML
la source
StatusEnum
est défini dans l'une des.ts
classes. Dans le composant angulaire que vous importez, liez-le à une propriété de composant (icistatusEnum
) et les propriétés de composant sont accessibles à partir du modèle.Angular4 - Utilisation d'énumération dans le modèle HTML ngSwitch / ngSwitchCase
Solution ici: https://stackoverflow.com/a/42464835/802196
crédit: @snorkpete
Dans votre composant, vous avez
Ensuite, dans votre composant, vous introduisez le type Enum via un membre 'MyEnum', et créez un autre membre pour votre variable enum 'myEnumVar':
Vous pouvez maintenant utiliser myEnumVar et MyEnum dans votre modèle .html. Par exemple, en utilisant des énumérations dans ngSwitch:
la source
à partir de rc.6 / final
...
la source
Comme alternative au décorateur de @Eric Lease, qui malheureusement ne fonctionne pas avec
--aot
(et donc--prod
) les builds, j'ai eu recours à un service qui expose toutes les énumérations de mon application. Il suffit de l'injecter publiquement dans chaque composant qui le nécessite, sous un nom simple, après quoi vous pourrez accéder aux énumérations dans vos vues. Par exemple:Un service
N'oubliez pas de l'inclure dans la liste des fournisseurs de votre module.
Classe de composant
HTML du composant
la source
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 la sécurité de type. Par exemple, si vous choisissez l'approche indiquée dans mon autre réponse, vous avez peut-être déclaré TT dans votre composant quelque chose comme ceci:
Pour afficher une mise en page différente dans votre HTML, vous auriez un
*ngIf
pour chaque type de mise en page, et vous pourriez vous référer directement à l'énumération dans le HTML de votre composant:Cet exemple utilise un service pour obtenir la disposition actuelle, l'exécute via le canal asynchrone, puis la compare à notre valeur d'énumération. C'est assez verbeux, alambiqué et pas très amusant à regarder. Il expose également le nom de l'énumération, qui lui-même peut être trop verbeux.
Alternative, qui conserve la sécurité de type du HTML
Vous pouvez également effectuer les opérations suivantes et déclarer une fonction plus lisible dans le fichier .ts de votre composant:
Beaucoup plus propre! Mais que faire si quelqu'un tape
'Horziontal'
par erreur? La seule raison pour laquelle vous vouliez utiliser une énumération dans le HTML était d'être de type sécurisé, n'est-ce pas?Nous pouvons toujours y parvenir avec keyof et une certaine magie dactylographiée. Voici la définition de la fonction:
Notez l'utilisation de
FeatureBoxResponsiveLayout[string]
qui convertit la valeur de chaîne transmise en valeur numérique de l'énumération.Cela donnera un message d'erreur avec une compilation AOT si vous utilisez une valeur non valide.
Actuellement, VSCode n'est pas assez intelligent pour être souligné
H4orizontal
dans l'éditeur HTML, mais vous recevrez l'avertissement au moment de la compilation (avec le commutateur --prod build ou --aot). Cela peut également être amélioré dans une future mise à jour.la source
html
mais je vois votre point et j'ai commencé à l'utiliser; ça fait le boulot, comme au bon vieux temps, lors de la compilation! :)Mon composant utilisait un objet
myClassObject
de typeMyClass
, qui lui-même utilisaitMyEnum
. Cela conduit au même problème décrit ci-dessus. Résolu le problème en faisant:puis en l'utilisant dans le modèle comme
la source
Si vous utilisez l'approche `` référence de typetable '' (de @Carl G) et que vous utilisez plusieurs tables de types, vous voudrez peut-être envisager de cette façon:
Accédez ensuite à votre fichier html avec
Je suis favorable à cette approche car elle indique clairement que vous faites référence à une table de types et évite également une pollution inutile de votre fichier de composants.
Vous pouvez également placer un global
TT
quelque part et y ajouter des énumérations si nécessaire (si vous le souhaitez, vous pouvez également créer un service comme indiqué par la réponse @VincentSels). Si vous avez de nombreuses tables de caractères, cela peut devenir fastidieux.De plus, vous les renommez toujours dans votre déclaration pour obtenir un nom plus court.
la source