Передача перечислений в шаблонах просмотра angular2

123

Можем ли мы использовать перечисления в шаблоне представления angular2?

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

передает строку в качестве ввода:

enum DropdownType {
    instrument,
    account,
    currency
}

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

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

        console.log(value);
    };
}

Но как передать конфигурацию enum? Я хочу что-то вроде этого в шаблоне:

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

Что было бы лучше всего?

Отредактировано: Создан пример:

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);
Маклак
источник
2
Лучше, чем оба приведенных ниже ответа, хотя они и похожи, но проще, чем принятый: stackoverflow.com/a/42464835/358578
pbarranis

Ответы:

132

Создайте свойство для своего перечисления в родительском компоненте для своего класса компонента и назначьте ему перечисление, а затем укажите это свойство в своем шаблоне.

export class Parent {
    public dropdownTypes = DropdownType;        
}

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

Это позволяет вам перечислить перечисление, как ожидалось, в вашем шаблоне.

<div class="Dropdown" [dropdownType]="dropdownTypes.instrument"></div>
Дэвид Л
источник
2
На основе вашего обновления переместите объявление свойства enum в родительский компонент.
David L
Да, конечно, исходя из контекста.
McLac
8
Опять же, голосующий против, пожалуйста, поделитесь своим мнением о том, как можно улучшить этот ответ, если вы с ним не согласны.
David L
1
В случае, если кто-то изо всех сил пытается заставить это работать, обратите внимание, что в приведенном выше коде это «set dropdownType ()», а не «setDropDownType ()». Мне потребовалось время, чтобы увидеть это. Однако он также работает с переменной-членом.
Мюррейк
2
Совершенно уверен, что dropdownTypeв шаблоне должны быть квадратные скобки на обоих концах (например, так :), [dropdownType]поскольку он принимает переменную, а не текст.
Tom
170

Создать перечисление

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

Создайте свой компонент, убедитесь, что ваш список перечислений будет иметь тип

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

Создайте свой вид

<li [ngClass]="{'active':active==ACTIVE_OPTIONS.HOME}">
    <a router-link="/in">
    <i class="fa fa-fw fa-dashboard"></i> Home
    </a>
</li>
Освальдо Альварес
источник
4
Лучшее решение, чем принятое. Я думаю, он использует какую-то новую функцию TS.
Грег Дэн
2
Сам я не специалист, поэтому мне действительно нужно задаться вопросом: всегда ли это решение лучше, чем у Дэвида Л.? Это требует меньше строк кода, но с точки зрения использования памяти он может создавать один список для каждого экземпляра класса компонента хоста ... И если это правда (не говоря, что это так!), Нет большой проблемы, когда имеет дело с AppComponent, но решение может быть не лучшим в случае CustomerComponent или чего-то более повторяющегося. Я прав?
Руй Пиментел
2
Вы можете обновить html как: [class.active] = "active === ACTIVE_OPTIONS.HOME"
Нил
6
как и почему это лучше принятого решения @GregDan?
Адитья Викас Деварапалли
1
Адитья, это лучше по той простой причине, что он включает один класс, а не 2. У меня нет родительского класса, и я не собираюсь его создавать по этой причине :)
Юрий Гридин
13

Если вы хотите получить имя Enum:

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

затем в файле компонента

public gender: typeof Gender = Gender;

в шаблоне

<input [value]="gender.Man" />
Милад Джафари
источник
2

Может, тебе и не нужно этого делать.

Например, в Numeric Enum:

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

В шаблоне HTML:

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

результат: dropdownType == DropdownType.account

или String Enum:

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

результат: dropdownType == DropdownType.currency


Если вы хотите получить имя Enum:

val enumValue = DropdownType.currency
DropdownType[enumValue] //  print "currency", Even the "numeric enum" is also. 
Бин Чжан
источник
1
Допустим, я не даю перечислению никакого значения, если я изменю порядок перечисления, HTML будет неправильным. Думаю, это не лучший подход
Андре Рогжери Кампос