Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to utilize Typescript enum in angular HTML pages (e.g. angular ng-class)

Tags:

New to angular and typescript.

I have typescript enum as follows

public enum MyEnum{    A = 0,    B = 1,    C = 2 } 

A scope variable as-

$scope.myLetter: MyEnum = MyEnum.B; 

What is the correct way to put the enum check?

Option 1: Compare the integer value of enum in html page-

<div ng-class="{classA: myLetter === 0, classB: myLetter === 1, classC: myLetter === 2}">Test panel</div> 

Option 2: Get the class name from the controller scope method

$scope.getClass(value: myLetter): string{     if(value === MyEnum.A)     return 'classA';      if(value === MyEnum.B)     return 'classB';      if(value === MyEnum.C)     return 'classC'; } 

And to have html element as-

<div ng-class='getClass(myLetter)'>Test panel</div> 

Option 3: answer given by 'RyanNerd' at Angular.js and ng-switch-when - emulating enum

For me option 2 is preferable, remaining options have checks in ng-class value as string, which will not give us static type enforcement. Please share your views or any other better option if you have.

like image 268
Magnum23 Avatar asked Jul 29 '15 14:07

Magnum23


People also ask

Can I use enum in HTML angular?

The TypeScript enum can be used directly in your class, but it has to be assigned to a local variable to be used in the template. The template can work only with your local variable and not the enum self. The template can access only objects exposed by the controller or the component.

How to use enum in component angular?

and assign the enum to a public field in the class: import { State } from "../models/app-enums. model"; @Component({ .... }) export class AbcComponent implements OnInit { public StateEnum = State; public state = State.

When to use enum in angular?

Enums let you avoid using strings and having to remember what string values you used. They also allow you to lock down the values a property can be, so that a user can't just submit any value they want. So if you aren't using them, start using them, and if you are already using them, use them more, use them to a fault.


2 Answers

Get the class name from the controller scope method

I do not like an idea of making controller to know class names.

  1. You can add converter function to the scope:

    $scope.myEnumName = (value: MyEnum) => MyEnum[value]; 

    and use it in template:

    ng-class="{'A':'ClassA', 'B':'ClassB', 'C':'ClassC'}[myEnumName(myLetter)]" 
  2. Or add switch function

    $scope.switchMyEnum =     <T>(value: MyEnum, cases: { [value: string]: T }) => cases[MyEnum[value]]; 

    template:

    ng-class="switchMyEnum(myLetter, {'A':'ClassA', 'B':'ClassB', 'C':'ClassC'}) 
  3. If you need only myLetter switch:

    $scope.switchMyLetter =     <T>(cases: { [value: string]: T }) => cases[MyEnum[$scope.myLetter]]; 

    template:

    ng-class="switchMyLetter({'A':'ClassA', 'B':'ClassB', 'C':'ClassC'}) 
  4. If you want to use a number of enums in many scopes:

    angular.module("MyApp", [])   .run(["$rootScope", (root: {}) => {     function registerSwitchers(...enumInfos: [string, { [value: number]: string }][]) {       enumInfos.forEach(enumInfo => {         var switcherName = enumInfo[0]         var enumType = enumInfo[1]         root[switcherName] = (value: any, cases: { [value: string]: any }) => cases[enumType[value]];       });     }     registerSwitchers(       ["switchMyEnum1", MyEnum1],       ["switchMyEnum2", MyEnum2]);   }]) 
like image 191
Artem Avatar answered Sep 18 '22 13:09

Artem


You could also build the class object in your controller and set it as expression (with bracket notation) in your view.

Example:-

$scope.panelClass = {}; $scope.panelClass[MyEnum.A] = 'classA'; $scope.panelClass[MyEnum.B] = 'classB'; $scope.panelClass[MyEnum.C] = 'classC'; 

You can write the above as shorthand syntax (ES6), provided your typescript version supports (has polyfill support) it, so you can rewrite as:

$scope.panelClass = {     [MyEnum.A]:'classA',     [MyEnum.B]:'classB',      [MyEnum.C]:'classC' }; 

and use it as:

<div ng-class="panelClass[myLetter]">Test panel</div> 

This is similar to the shorthand ng-class expression:

<div ng-class="{0:'classA', 1:'classB', 2:'classC'}[myLetter]">Test panel</div> 
like image 35
PSL Avatar answered Sep 21 '22 13:09

PSL