[typescript] Angular2 ngSwitch 문에서 typescript 열거 형 값을 사용하는 방법

Typescript 열거 형은 Angular2의 ngSwitch 지시문과 자연스럽게 일치하는 것 같습니다. 그러나 구성 요소 템플릿에서 열거 형을 사용하려고하면 “정의되지 않은 속성 ‘xxx’을 읽을 수 없습니다 …”가 나타납니다. 구성 요소 템플릿에서 열거 형 값을 사용하려면 어떻게해야합니까?

이것은 열거 형 (ngFor)의 모든 값을 기반으로 html 선택 옵션을 만드는 방법과 다릅니다. 이 질문은 열거 형의 특정 값을 기반으로 한 ngSwitch에 관한 것입니다. 열거 형에 대한 클래스 내부 참조를 만드는 동일한 접근 방식이 나타납니다.



답변

구성 요소 클래스에서 열거 형에 대한 참조를 만들고 (방금 초기 문자를 소문자로 변경) 템플릿 ( plunker ) 에서 해당 참조를 사용할 수 있습니다 .

import {Component} from 'angular2/core';

enum CellType {Text, Placeholder}
class Cell {
  constructor(public text: string, public type: CellType) {}
}
@Component({
  selector: 'my-app',
  template: `
    <div [ngSwitch]="cell.type">
      <div *ngSwitchCase="cellType.Text">
        {{cell.text}}
      </div>
      <div *ngSwitchCase="cellType.Placeholder">
        Placeholder
      </div>
    </div>
    <button (click)="setType(cellType.Text)">Text</button>
    <button (click)="setType(cellType.Placeholder)">Placeholder</button>
  `,
})
export default class AppComponent {

  // Store a reference to the enum
  cellType = CellType;
  public cell: Cell;

  constructor() {
    this.cell = new Cell("Hello", CellType.Text)
  }

  setType(type: CellType) {
    this.cell.type = type;
  }
}


답변

열거 형을 인식하도록 구성 요소에 추가 할 사용자 지정 데코레이터를 만들 수 있습니다.

myenum.enum.ts :

export enum MyEnum {
    FirstValue,
    SecondValue
}

myenumaware.decorator.ts

import { MyEnum } from './myenum.enum';

export function MyEnumAware(constructor: Function) {
    constructor.prototype.MyEnum = MyEnum;
}

enum-aware.component.ts

import { Component } from '@angular2/core';
import { MyEnum } from './myenum.enum';
import { MyEnumAware } from './myenumaware.decorator';

@Component({
  selector: 'enum-aware',
  template: `
    <div [ngSwitch]="myEnumValue">
      <div *ngSwitchCase="MyEnum.FirstValue">
        First Value
      </div>
      <div *ngSwitchCase="MyEnum.SecondValue">
        Second Value
      </div>
    </div>
    <button (click)="toggleValue()">Toggle Value</button>
  `,
})
@MyEnumAware // <---------------!!!
export default class EnumAwareComponent {
  myEnumValue: MyEnum = MyEnum.FirstValue;

  toggleValue() {
    this.myEnumValue = this.myEnumValue === MyEnum.FirstValue
        ? MyEnum.SecondValue : MyEnum.FirstValue;
  }
}


답변

이것은 간단하고 매력처럼 작동합니다 🙂 그냥 열거 형을 선언하면 HTML 템플릿에서 사용할 수 있습니다

  statusEnum: typeof StatusEnum = StatusEnum;


답변

Angular4-HTML 템플릿에서 Enum 사용 ngSwitch / ngSwitchCase

여기에 해결책 : https://stackoverflow.com/a/42464835/802196

크레딧 : @snorkpete

귀하의 구성 요소에는

enum MyEnum{
  First,
  Second
}

그런 다음 구성 요소에서 멤버 ‘MyEnum’을 통해 Enum 유형을 가져오고 열거 형 변수 ‘myEnumVar’에 대한 다른 멤버를 만듭니다.

export class MyComponent{
  MyEnum = MyEnum;
  myEnumVar:MyEnum = MyEnum.Second
  ...
}

이제 .html 템플릿에서 myEnumVar 및 MyEnum을 사용할 수 있습니다. 예를 들어, ngSwitch에서 열거 형 사용 :

<div [ngSwitch]="myEnumVar">
  <div *ngSwitchCase="MyEnum.First"><app-first-component></app-first-component></div>
  <div *ngSwitchCase="MyEnum.Second"><app-second-component></app-second-component></div>
  <div *ngSwitchDefault>MyEnumVar {{myEnumVar}} is not handled.</div>
</div>


답변

rc.6 현재 / 최종

export enum AdnetNetworkPropSelector {
    CONTENT,
    PACKAGE,
    RESOURCE
}

<div style="height: 100%">
          <div [ngSwitch]="propSelector">
                 <div *ngSwitchCase="adnetNetworkPropSelector.CONTENT">
                      <AdnetNetworkPackageContentProps [setAdnetContentModels]="adnetNetworkPackageContent.selectedAdnetContentModel">
                                    </AdnetNetworkPackageContentProps>
                  </div>
                 <div *ngSwitchCase="adnetNetworkPropSelector.PACKAGE">
                </div>
            </div>
        </div>


export class AdnetNetwork {
    private adnetNetworkPropSelector = AdnetNetworkPropSelector;
    private propSelector = AdnetNetworkPropSelector.CONTENT;
}


답변

불행하게도 사용하여 작동하지 않습니다 @Eric리스의 장식에 대한 대안으로서, --aot(따라서 --prod) 빌드, 나는 내 모든 응용 프로그램의 열거를 노출하는 서비스를 사용하는 의지. 쉬운 이름으로 필요한 각 구성 요소에 공개적으로 주입하면 뷰의 열거 형에 액세스 할 수 있습니다. 예 :

서비스

import { Injectable } from '@angular/core';
import { MyEnumType } from './app.enums';

@Injectable()
export class EnumsService {
  MyEnumType = MyEnumType;
  // ...
}

모듈의 공급자 목록에 포함시키는 것을 잊지 마십시오.

컴포넌트 클래스

export class MyComponent {
  constructor(public enums: EnumsService) {}
  @Input() public someProperty: MyEnumType;

  // ...
}

구성 요소 html

<div *ngIf="someProperty === enums.MyEnumType.SomeValue">Match!</div>


답변

정말로 하고 싶니?’를 고려하여 시작하십시오.

HTML에서 직접 열거 형을 참조하는 데 아무런 문제가 없지만 경우에 따라 유형 안전을 잃지 않는 더 깨끗한 대안이 있습니다. 예를 들어 다른 답변에 표시된 접근 방식을 선택하면 구성 요소에서 다음과 같이 TT를 선언했을 수 있습니다.

public TT =
{
    // Enum defines (Horizontal | Vertical)
    FeatureBoxResponsiveLayout: FeatureBoxResponsiveLayout
}

HTML에 다른 레이아웃을 표시하려면 *ngIf각 레이아웃 유형마다 하나씩 있으며 구성 요소의 HTML에서 열거 형을 직접 참조 할 수 있습니다.

*ngIf="(featureBoxResponsiveService.layout | async) == TT.FeatureBoxResponsiveLayout.Horizontal"

이 예제는 서비스를 사용하여 현재 레이아웃을 가져 와서 비동기 파이프를 통해 실행 한 다음 열거 형 값과 비교합니다. 꽤 장황하고 복잡하며 보는 것이별로 재미 있지 않습니다. 또한 열거 형의 이름을 공개하는데, 그 자체가 지나치게 장황 할 수 있습니다.

HTML에서 형식 안전성을 유지하는 대안

또는 다음을 수행하고 구성 요소의 .ts 파일에서 더 읽기 쉬운 함수를 선언 할 수 있습니다.

*ngIf="isResponsiveLayout('Horizontal')"

훨씬 더 깨끗합니다! 그러나 누군가 'Horziontal'실수로 입력하면 어떻게됩니까? HTML에서 열거 형을 사용하려는 모든 이유는 형식이 안전해야합니까?

우리는 여전히 keyof 와 일부 typescript 마술 로 그것을 달성 할 수 있습니다 . 이것은 함수의 정의입니다.

isResponsiveLayout(value: keyof typeof FeatureBoxResponsiveLayout)
{
    return FeatureBoxResponsiveLayout[value] == this.featureBoxResponsiveService.layout.value;
}

의 사용주의 FeatureBoxResponsiveLayout[string]하는 변환 열거의 숫자 값에 전달 된 문자열 값입니다.

잘못된 값을 사용하면 AOT 컴파일과 함께 오류 메시지가 표시됩니다.

“”H4orizontal “”유형의 인수는 “”Vertical “유형의 매개 변수에 지정할 수 없습니다. | “수평”

현재 VSCode는 H4orizontalHTML 편집기에서 밑줄을 긋기 에는 충분하지 않지만 컴파일 타임에 –prod build 또는 –aot 스위치를 사용하여 경고를 받게됩니다. 향후 업데이트에서도 개선 될 수 있습니다.