我如何使用ngFor作为字符串数组迭代Typescript Enum

Rob*_*man 49 angular2-template angular

我正在使用Angular2和Typscript.我有一个枚举:

export enum Role {
    ServiceAdmin, CompanyAdmin, Foreman, AgentForeman, 
    CrewMember, AgentCrewMember, Customer
}
Run Code Online (Sandbox Code Playgroud)

我想使用*ngFor迭代枚举.做这个的最好方式是什么?我必须创建一个管道吗?或者有更简单的方法吗?

yur*_*zui 60

枚举只是一个对象.

你的枚举在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
}
Run Code Online (Sandbox Code Playgroud)

所以你可以这样迭代它(plnkr):

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

或者更好地创建自定义管道:

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

更新

Typescript 2.4允许枚举成员包含字符串初始化器,如:

enum Colors {
    Red = "RED",
    Green = "GREEN",
    Blue = "BLUE",
}
Run Code Online (Sandbox Code Playgroud)

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

  • 实际上,在Angular 6中,您甚至不需要管道,只需在组件中使用`role = Object.keys(Role)`。 (4认同)
  • 在 angular 6 中,您可以只返回键数组,而不必在管道中将其中的一半切片:`return Object.keys(data);` (2认同)

Mur*_*ack 14

您可以只使用Angular 6.1中引入的“键值”管道。

<p *ngFor="let enum of TestEnum | keyvalue">
  {{ enum.key }} - {{ enum.value}}
</p>
Run Code Online (Sandbox Code Playgroud)

查看完整示例-> https://stackblitz.com/edit/angular-gujg2e

  • 这对我不起作用,因为 Angular 会迭代每个键和每个值...该功能必须在以后的版本中进行修改...:( (11认同)
  • 请记住,您不能像这样在 TestEnum 中直接使用枚举,您必须将枚举设置为变量,例如: public testEnum = TestEnum; 然后在循环中您可以使用 let enum of testEnum | 核心价值 (8认同)
  • 它有效,但按字母顺序对枚举的顺序进行排序。 (7认同)
  • 它仅适用于字符串初始化器 (3认同)
  • @RRaj您可以控制排序顺序:/sf/answers/3695595501/ (3认同)
  • @fonzane,似乎由于枚举是默认数字,因此 ts 映射名称和值的 k/v 对;以及值和名称(我猜是为了索引)...为了解决这个问题,我将我的(字符串)枚举映射到一个值:`enum Food { Chips = 'chips', Fish = 'fish' }`,这解决了问题。这里有更好的细节,https://www.angularjswiki.com/angular/names-of-enums-typescript/ (2认同)

Gün*_*uer 11

模板的范围是组件实例.如果要访问此范围之外的内容,则需要使用组件实例使其可用:

@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 | enumsToArray">{{item.index}}: {{item.name}}</div>`
})
class MyComponent {
  roles = Role;
}
Run Code Online (Sandbox Code Playgroud)

另请参见/sf/answers/2502517671/


Rob*_*man 7

经过对其他答案的进一步研究和回顾,我现在可以为我的问题制定答案.我认为只有在组件中没有代码支持的情况下才能使用*ngFor迭代枚举.代码支持可以包含构造函数代码,它将Enum转换为某种类型的数组,或者我们可以创建一个执行类似操作的自定义管道.


Fil*_*rge 7

我需要做同样的事情,也许这就是你想要的.
更多DRY,它也可以使用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);
  }
}
Run Code Online (Sandbox Code Playgroud)

切片之前的对象输出

{
    "1",
    "2",
    "3",
    "4",
    "5",
    "6",
    "7",
    "ServiceAdmin",
    "CompanyAdmin",
    "Foreman",
    "AgentForeman",
    "CrewMember",
    "AgentCrewMember",
    "Customer",
    "keys"
}
Run Code Online (Sandbox Code Playgroud)

typescript合并了两个声明,因此 keys.lenght-1

ngFor:

<div *ngFor="let role of Roles.keys()">{{ role }}</div>
Run Code Online (Sandbox Code Playgroud)

更多信息:
打字稿的声明合并

基于:
TypeScript:将函数添加到枚举 https://basarat.gitbooks.io/typescript/content/docs/enums.html(在枚举章的末尾.)


小智 5

export enum Priority {
  LL = 1,   // VERY LOW
  L = 2,    // LOW
  N = 3,    // NORMAL
  U = 4,    // HIGH
  UU = 5    // VERY HIGH
}
Run Code Online (Sandbox Code Playgroud)

您的角度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;
  }
}
Run Code Online (Sandbox Code Playgroud)


Ela*_*Tal 5

使用管道:

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]);
  }
}
Run Code Online (Sandbox Code Playgroud)

并在模板中:

<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>
Run Code Online (Sandbox Code Playgroud)