如何使用 ngFor 迭代类型脚本 Enum 作为字符串数组

我使用 Angular2和 TypeScript,我有一个枚举:

export enum Role {
ServiceAdmin, CompanyAdmin, Foreman, AgentForeman,
CrewMember, AgentCrewMember, Customer
}

我想使用 * ngFor 来迭代枚举。最好的方法是什么?我必须创建一个管道?还是有更简单的方法?

107302 次浏览

模板的作用域是组件实例。如果您想要访问这个范围之外的内容,那么您需要让它在您的组件实例中可用:

This also works if the enum keys do not start with 0

@Pipe({name: 'enumToArray'})
export class EnumToArrayPipe implements PipeTransform {
transform(value) : Object {
return Object.keys(value).filter(e => !isNaN(+e)).map(o => { return {index: +o, name: value[o]}});
}
}


@Component({
...
imports: [EnumsToArrayPipe],
template: `<div *ngFor="let item of roles | enumToArray">\{\{item.index}}: \{\{item.name}}</div>`
})
class MyComponent {
roles = Role;
}

See also https://stackoverflow.com/a/35750252/217408

枚举只是一个对象。

你的枚举在 JavaScript 中是这样写的:

{
0: "ServiceAdmin",
1: "CompanyAdmin",
2: "Foreman",
3: "AgentForeman",
4: "CrewMember",
5: "AgentCrewMember",
6: "Customer",
ServiceAdmin: 0,
CompanyAdmin: 1,
Foreman: 2,
AgentForeman: 3,
CrewMember: 4,
AgentCrewMember: 5,
Customer: 6
}

所以你可以这样迭代它(普林克) :

@Component({
...
template: `
<div *ngFor="let item of keys()">
\{\{ item }}
</div>
`
})
export class YourComponent {
role = Role;
keys() : Array<string> {
var keys = Object.keys(this.role);
return keys.slice(keys.length / 2);
}
}

最好是创建自定义管道:

@Pipe({
name: 'enumToArray'
})
export class EnumToArrayPipe implements PipeTransform {
transform(data: Object) {
const keys = Object.keys(data);
return keys.slice(keys.length / 2);
}
}

Example

更新

类型脚本2.4允许枚举成员包含字符串初始值设定项,如:

enum Colors {
Red = "RED",
Green = "GREEN",
Blue = "BLUE",
}

在这种情况下,您可以只从管道返回 Object.keys(data);

在进一步研究和回顾其他答案之后,我现在可以对我的问题做出回答了。我认为在组件中没有一些代码支持的情况下,仅使用 * ngFor 来迭代枚举是不可能的。代码支持可以由构造函数代码组成,构造函数代码将 Enum 转换成某种类型的数组,或者我们可以创建一个自定义管道来执行类似的操作。

我需要做同样的事情,也许这就是你想要的。
更多的干燥,它也可以与 module一起使用。

export enum Role {
ServiceAdmin, CompanyAdmin, Foreman, AgentForeman,
CrewMember, AgentCrewMember, Customer
}


export namespace Role {


export function keys(): Array<string>{
var keys = Object.keys(Role);
return keys.slice(keys.length / 2, keys.length-1);
}
}

切片之前的对象输出

{
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"ServiceAdmin",
"CompanyAdmin",
"Foreman",
"AgentForeman",
"CrewMember",
"AgentCrewMember",
"Customer",
"keys"
}

Type 脚本合并了这两个声明,因此使用了 keys.lenght-1

and the ngFor:

<div *ngFor="let role of Roles.keys()">\{\{ role }}</div>

更多信息:
字体声明合并

基于:
TypeScript: 向枚举添加函数 Https://basarat.gitbooks.io/typescript/content/docs/enums.html (见 enums章末)

我有枚举:

export enum FileCategory {
passport = 'Multipass',
agreement = 'Personal agreement',
contract = 'Contract',
photo = 'Self photos',
other = 'Other'
}

在组件 ts 文件中:

export class MyBestComponent implements OnInit {
fileCategory = FileCategory;


// returns keys of enum
fileKeys(): Array<string> {
const keys = Object.keys(this.fileCategory);
return keys;
}


// returns values of enum
fileVals(): Array<string> {
const keys = Object.keys(this.fileCategory);
return keys.map(el => Object(this.fileCategory)[el]);
}

在 HTML 模板中显示这些枚举的值和键:

  <a *ngFor="let cat of fileVals()"
(click)="addFileCategory(cat)">\{\{cat}}</a>
<a *ngFor="let cat of fileKeys()"
(click)="addFileCategory(cat)">\{\{cat}}</a>
export enum Priority {
LL = 1,   // VERY LOW
L = 2,    // LOW
N = 3,    // NORMAL
U = 4,    // HIGH
UU = 5    // VERY HIGH
}

Your angular component.ts :

import { Priority } from './../shared/core/config/datas.config';


@Component({
selector: 'app-yourcomponent',
template: `
<ng-container *ngFor="let p of getPriority">
<div> \{\{p.key}} / \{\{p.value}} </div>
</ng-container>
`
})


export class YourComponent {
getPriority = this.getENUM(Priority);


getENUM(ENUM:any): string[] {
let myEnum = [];
let objectEnum = Object.keys(ENUM);
const values = objectEnum.slice( 0 , objectEnum.length / 2 );
const keys = objectEnum.slice( objectEnum.length / 2 );


for (let i = 0 ; i < objectEnum.length/2 ; i++ ) {
myEnum.push( { key: keys[i], value: values[i] } );
}
return myEnum;
}
}

在角度7中,在使用 key ()时仍然获得所有键和值的列表。

Based on the above answers I am using this for a simple ENUM, seems cleaner and more OO:

export enum CategoryType {
Type1,
Type2,
...,
}


export namespace CategoryType {
export function keys() {
return Object.keys(CategoryType).filter(k => !isNaN(Number(k)));
}
}

then in the template:

<option *ngFor="let type of types.keys()" [value]="type">\{\{types[type]}}</option>

该函数成为枚举中的另一个条目,但像其他非数字一样被过滤掉。

我建议您使用一个通用的管道,它将更加灵活,在您的代码中更少的冗余。 The problem with some previous propositions is that the typescript allow you to have different kind of enum, not only number/string.

例如:

export enum NotificationGrouping {
GroupByCreatedAt = "GroupByCreatedAt",
GroupByCreatedByUser = "GroupByCreatedByUser",
GroupByEntity = "GroupByEntity",
GroupByAction = "GroupByAction",
}

Here is my solution:

import { Pipe, PipeTransform } from '@angular/core';


@Pipe({
name: 'enumToArray'
})
export class EnumToArrayPipe implements PipeTransform {


transform(value, args: string[]): any {
let result = [];
var keys = Object.keys(value);
var values = Object.values(value);
for (var i = 0; i < keys.length; i++) {
result.push({ key: keys[i], value: values[i] });
}
return result;
//or if you want to order the result:
//return result.sort((a, b) => a.value < b.value ? -1 : 1);
}
}

and the html will be:

<mat-select [(ngModel)]="groupKey">
<mat-option *ngFor="let group of notificationGrouping | enumToArray"
[value]="group.key">
\{\{ group.value }}
</mat-option>
</mat-select>

在其中:

public notificationGrouping : NotificationGrouping

注意: 看到人们在没有解释的情况下给出一个减号仍然很有趣... ... 对于其他可能对这个解决方案感兴趣的人,我可以确认它是正确工作的。

你可以直接使用角度6.1中引入的“ keyvalue”管道。

<p *ngFor="let enum of TestEnum | keyvalue">
\{\{ enum.key }} - \{\{ enum.value}}
</p>

这里有一个完整的例子-> https://stackblitz.com/edit/angular-gujg2e

使用管道:

import { Pipe, PipeTransform } from '@angular/core';


@Pipe({
name: 'enum'
})
export class EnumSelectPipe implements PipeTransform {
transform(value: any): [number, string][] {
return Object.keys(value).filter(t => isNaN(+t)).map(t => [value[t], t]);
}
}

在模板中:

<mat-select formControlName="type" placeholder="Package Type">
<mat-option *ngFor="let pType of PackageTypes | enum" [value]="pType[0]">\{\{ pType[1] | title}}</mat-option>
</mat-select>

ES6 支持

export enum E {
a = 'First',
b = 'Second',
c = 'Third'
}


let keyValueArray = Object.keys(E).map(k => ({key: k, value: E[k as any]}));
 fillKeysValueFromEnum<T>(type:T){
return Object.keys(type).filter(t => isNaN(+t)).map(el => {
return {
key: el,
value: Object(type)[el]
}
});
}

然后

fillKeysValueFromEnum(ENUM_HERE)

我已经很晚了,我的回答可能不能直接解决问题,但它可以完成工作。今天我遇到了一个问题,它围绕着同样的问题,即迭代 enum

我开始创建一个 object而不是使用 enum

export const Roles= {
0: "ServiceAdmin", 1: "CompanyAdmin", 2: "Foreman", 3: "AgentForeman",
4: "CrewMember", 5: "AgentCrewMember", 6: "Customer"
}

To iterate use like below:

let Number=Number;
let roles= Roles; // in .ts file
<select>
<option *ngFor="let role of roles | keyvalue" [value]="Number(\{\{role.key}})">
\{\{role.value}}
</option>
</select>

To parse a value use like below:

let selectedRoleValue= 4;
let Roles= Roles; // in .ts file


<div>\{\{Roles[selectedRoleValue]}}</div>

这将显示

船员