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는 H4orizontal
HTML 편집기에서 밑줄을 긋기 에는 충분하지 않지만 컴파일 타임에 –prod build 또는 –aot 스위치를 사용하여 경고를 받게됩니다. 향후 업데이트에서도 개선 될 수 있습니다.