Comment puis-je utiliser ngFor pour itérer sur Enum dactylographié comme un tableau de chaînes

J'utilise Angular2 et dactylographié. J'ai un enum:

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

je veux utiliser *ngFor pour itérer au-dessus de l'enum. Quelle est la meilleure façon de le faire? Dois-je en créer un Tuyau? Ou est-il un moyen plus simple?

25
demandé sur Rob Gorman 2016-07-24 20:05:10

6 réponses

un enum n'est qu'un objet.

votre enum est écrit quelque chose comme ceci en 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
}

donc vous pouvez itérer de cette façon ( 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);
    }
}

Ou serait préférable de créer des pipe :

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

exemple

Mise à jour

Tapescript 2.4 permet aux membres enum de contenir des initialiseurs de chaîne comme:

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

dans ce cas, vous pouvez simplement retourner Object.keys(data); de la conduite.

34
répondu yurzui 2018-07-16 10:24:19

la portée du template est l'instance component. Si vous voulez accéder à quelque chose en dehors de cette portée, vous devez le rendre disponible à partir de l'instance de votre composant:

@Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform {
  transform(value, args:string[]) : any {
    let keys = [];
    for (var enumMember in value) {
      var isValueProperty = parseInt(enumMember, 10) >= 0
      if (isValueProperty) {
        keys.push({key: enumMember, value: value[enumMember]});
        // Uncomment if you want log
        // console.log("enum member: ", value[enumMember]);
      } 
    }
    return keys;
  }
}

@Component({
  ...
  pipes: [KeysPipe],
  template: `<div *ngFor="let item of roles | keys">{{item}}</div>`
})
class MyComponent {
  roles = Role;
}

Voir aussi https://stackoverflow.com/a/35750252/217408

10
répondu Günter Zöchbauer 2017-05-23 12:18:16

j'avais besoin de faire la même chose et peut-être que c'est ce que vous vouliez.

Plus sec et il peut être utilisé avec module aussi.

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);
  }
}

la sortie objet avant la tranche

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

typographique fusionne les deux déclarations d'où le keys.lenght-1

et le ngFor :

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

plus d'informations:

déclaration dactylographiée fusionnant

basé sur:

Tapescript: ajouter des fonctions à un Enum https://basarat.gitbooks.io/typescript/content/docs/enums.html (à la fin du chapitre enums .)

7
répondu Filipe Morais Jorge 2017-11-18 21:29:02

après d'autres recherches et l'examen des autres réponses, je peux maintenant formuler une réponse à ma question. Je pense qu'il n'est pas possible d'utiliser simplement *ngFor pour itérer sur un enum sans un support de code dans le composant. Le support du code peut consister en du code de constructeur qui transforme L'Enum en une sorte de tableau ou nous pouvons créer un tuyau personnalisé qui fait quelque chose de similaire.

4
répondu Rob Gorman 2016-07-25 17:41:00
export enum Priority {
  LL = 1,   // VERY LOW
  L = 2,    // LOW
  N = 3,    // NORMAL
  U = 4,    // HIGH
  UU = 5    // VERY HIGH
}

votre composante angulaire.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;
  }
}
3
répondu Neo_Ryu 2018-06-26 08:59:32

j'ai l'enum:

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

dans le fichier de composants 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]);
  }

dans le modèle HTML afficher ces valeurs et clés d'enum:

  <a *ngFor="let cat of fileVals()"
     (click)="addFileCategory(cat)">{{cat}}</a>
  <a *ngFor="let cat of fileKeys()"
     (click)="addFileCategory(cat)">{{cat}}</a>
1
répondu Pax Beach 2018-04-10 14:10:21