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.
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.
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.
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.
Get the class name from the controller scope method
I do not like an idea of making controller to know class names.
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)]"
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'})
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'})
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]); }])
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With