124 votes

Comment puis-je utiliser ngFor pour itérer sur une somme de type script comme un tableau de chaînes de caractères ?

J'utilise Angular2 et TypeScript et j'ai un enum :

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

Je veux utiliser *ngFor pour itérer sur l'enum. Quelle est la meilleure façon de procéder ? Dois-je créer un Pipe ? Ou existe-t-il un moyen plus simple ?

1 votes

Veuillez envisager de mettre à jour la réponse acceptée en adoptant celle de Murolack, qui est la plus simple et la plus récente. Merci !

112voto

yurzui Points 85802

Un enum est juste un objet.

Votre enum s'écrit 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
}

Vous pouvez donc l'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 il serait préférable de créer un tuyau personnalisé :

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

Ejemplo

Mise à jour

Typescript 2.4 permet aux membres d'un enum de contenir des initialisateurs de chaîne comme :

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

dans ce cas, vous pouvez simplement retourner Object.keys(data); du tuyau.

0 votes

Cela ne fonctionne pas bien si l'on inclut des valeurs négatives. btw : le plnkr ne fonctionne plus.

0 votes

@MA-Maddin Mise à jour de plunker

1 votes

Si vous utilisez le tuyau personnalisé dans un module partagé, n'oubliez pas d'ajouter EnumToArrayPipe dans les exportations.

17voto

Günter Zöchbauer Points 21340

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

Cela fonctionne également si les clés de l'énumération ne commencent pas par 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;
}

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

1 votes

Merci pour votre aide. Je viens d'essayer mais j'obtiens l'erreur "NgFor ne prend en charge que les liaisons avec des objets itérables tels que les tableaux". Il semble donc que je puisse créer un tube pour transformer les rôles en un tableau d'énumérations ou de chaînes de caractères. Mais il me semble que je devrais être en mesure de le faire nativement d'une manière ou d'une autre.

0 votes

Désolé, j'ai oublié le tuyau. J'ai mis à jour ma réponse.

1 votes

Merci ! Une meilleure solution que le cast to Array :-)

9voto

J'avais besoin de faire la même chose et peut-être que c'est ce que tu voulais.
Plus DRY 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 de l'objet avant la tranche

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

Le script de type fusionne les deux déclarations, d'où l'utilisation de l'attribut keys.lenght-1

et le ngFor :

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

Plus d'informations :
Fusion de la déclaration de Typescript

basé sur :
TypeScript : Ajout de fonctions à un Enum https://basarat.gitbooks.io/typescript/content/docs/enums.html (à la fin du enums chapitre).

1 votes

Et pour obtenir les valeurs, vous feriez le contraire : let values = Object.keys(ApplicationMode) ; return values.slice(0, values.length / 2) ; Merci pour l'idée.

0 votes

Il n'y a pas d'entrée "keys" avant le slice donc vous n'avez pas besoin de keys.lenght-1

7voto

Rob Gorman Points 1456

Après une recherche plus approfondie 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 une énumération sans un support de code dans le composant. Le support de code peut consister en un code constructeur qui transforme l'Enum en une sorte de tableau ou nous pouvons créer un tube personnalisé qui fait quelque chose de similaire.

6voto

Neo_Ryu Points 51
export enum Priority {
  LL = 1,   // VERY LOW
  L = 2,    // LOW
  N = 3,    // NORMAL
  U = 4,    // HIGH
  UU = 5    // VERY HIGH
}

Votre composant 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;
  }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X