McLac
McLac

Reputation: 2753

Pass enums in angular2 view templates

Can we use enums in an angular2 view template?

<div class="Dropdown" dropdownType="instrument"></div>

passes the string as input:

enum DropdownType {
    instrument,
    account,
    currency
}

@Component({
    selector: '[.Dropdown]',
})
export class Dropdown {

    @Input() public set dropdownType(value: any) {

        console.log(value);
    };
}

But how to pass an enum configuration? I want something like this in the template:

<div class="Dropdown" dropdownType="DropdownType.instrument"></div>

What would be the best practice?

Edited: Created an example:

import {bootstrap} from 'angular2/platform/browser';
import {Component, View, Input} from 'angular2/core';

export enum DropdownType {

    instrument = 0,
    account = 1,
    currency = 2
}

@Component({selector: '[.Dropdown]',})
@View({template: ''})
export class Dropdown {

    public dropdownTypes = DropdownType;

    @Input() public set dropdownType(value: any) {console.log(`-- dropdownType: ${value}`);};
    constructor() {console.log('-- Dropdown ready --');}
}

@Component({ selector: 'header' })
@View({ template: '<div class="Dropdown" dropdownType="dropdownTypes.instrument"> </div>', directives: [Dropdown] })
class Header {}

@Component({ selector: 'my-app' })
@View({ template: '<header></header>', directives: [Header] })
class Tester {}

bootstrap(Tester);

Upvotes: 178

Views: 119446

Answers (5)

deelk00
deelk00

Reputation: 11

I'm a bit late to the party.

You can use ...set (value: keyof DropdownType)...

That way the function can only be called with a key from the enum.

After that you just have to convert the string value to the enum value. This is not directly possible in TypeScript, but we can use a workaround:

An enum in TS will be compiled to

var DropdownType = {
    instrument = 0,
    account = 1,
    currency = 2
};

Object.freeze(DropdownType);

Since after the compilation the enum becomes an immutable object, we can use the name of the key as indexer. We just have to work around the compiler:

@Input() public set dropdownType(value: keyof DropdownType) {
    const enumValue = (DropdownType as any)[value] as DropdownType;
    console.log(enumValue);
};

Beware though, if an enum type gets added to JS this will probably not work anymore. And since we are working around the compiler, it will not warn you about any error that occurs.

Furthermore will Autocompletion only work if your IDE is smart enough for that. My VSCode Workspace does not Autocomplete, but WebStorm does.

Edit:

If you use enums more frequently this way, I would suggest creating a static helper function somewhere in the project:

function getValueFromEnum<T extends {[key: string]: string | number}>(
    e: T, 
    key: keyof T
) {
    return e[key];
}

Upvotes: 0

Milad Jafari
Milad Jafari

Reputation: 975

If you want get Enum name :

export enum Gender {
  Man = 1,
  Woman = 2
}

then in component file

public gender: typeof Gender = Gender;

in template

<input [value]="gender.Man" />

Upvotes: 42

Oswaldo Alvarez
Oswaldo Alvarez

Reputation: 4812

Create an Enum:

enum ACTIVE_OPTIONS {
  HOME = 0,
  USERS = 1,
  PLAYERS = 2
}

Create a component, be sure your enum list will have the typeof:

export class AppComponent {
  ACTIVE_OPTIONS = ACTIVE_OPTIONS;
  active: ACTIVE_OPTIONS;
}

Create a template:

<li [ngClass]="{ 'active': active === ACTIVE_OPTIONS.HOME }">
  <a routerLink="/in">
    <i class="fa fa-fw fa-dashboard"></i> Home
  </a>
</li>

Upvotes: 218

zbin
zbin

Reputation: 332

Maybe you don't have to do this.

For example, in Numeric Enum:

export enum DropdownType {
    instrument = 0,
    account = 1,
    currency = 2
}

In HTML Template:

<div class="Dropdown" [dropdownType]="1"></div>

result: dropdownType == DropdownType.account

or String Enum:

export enum DropdownType {
    instrument = "instrument",
    account = "account",
    currency = "currency"
}
<div class="Dropdown" [dropdownType]="'currency'"></div>

result: dropdownType == DropdownType.currency


If you want get Enum name :

val enumValue = DropdownType.currency
DropdownType[enumValue] //  print "currency", Even the "numeric enum" is also. 

Upvotes: 2

David L
David L

Reputation: 33823

Create a property for your enum on the parent component to your component class and assign the enum to it, then reference that property in your template.

export class Parent {
    public dropdownTypes = DropdownType;        
}

export class Dropdown {       
    @Input() public set dropdownType(value: any) {
        console.log(value);
    };
}

This allows you to enumerate the enum as expected in your template.

<div class="Dropdown" [dropdownType]="dropdownTypes.instrument"></div>

Upvotes: 165

Related Questions