J'ai cette énumération (j'utilise TypeScript):
export enum CountryCodeEnum {
France = 1,
Belgium = 2
}
Je voudrais construire un select dans mon formulaire, avec pour chaque option la valeur entière enum en tant que valeur et le texte enum en tant qu'étiquette, comme ça :
<select>
<option value="1">France</option>
<option value="2">Belgium</option>
</select>
Comment puis-je faire ceci ?
update2 simplifié par la création d'un tableau
@Pipe({name: 'enumToArray'})
export class EnumToArrayPipe implements PipeTransform {
transform(value) : Object {
return Object.keys(value).filter(e => !isNaN(+e)).map(e => {return {[e]: value[e]}})
}
}
@Component({
...
imports: [EnumsToArrayPipe],
template: `<div *ngFor="let item of roles | enumsToArray; let idx=index">{{idx}}: {{item}}</div>`
})
class MyComponent {
roles = Role;
}
mettre à jour
au lieu de pipes: [KeysPipe]
utilisation
@NgModule({
declarations: [KeysPipe],
exports: [KeysPipe],
}
export class SharedModule{}
@NgModule({
...
imports: [SharedModule],
})
original
Utilisation du canal keys
de https://stackoverflow.com/a/35536052/217408
Je devais modifier un peu le tuyau pour le faire fonctionner correctement avec enums (voir aussi Comment obtenir les noms des entrées enum? )
@Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform {
transform(value, args:string[]) : any {
let keys = [];
for (var enumMember in value) {
if (!isNaN(parseInt(enumMember, 10))) {
keys.Push({key: enumMember, value: value[enumMember]});
// Uncomment if you want log
// console.log("enum member: ", value[enumMember]);
}
}
return keys;
}
}
@Component({ ...
pipes: [KeysPipe],
template: `
<select>
<option *ngFor="let item of countries | keys" [value]="item.key">{{item.value}}</option>
</select>
`
})
class MyComponent {
countries = CountryCodeEnum;
}
Une autre solution si vous ne voulez pas créer un nouveau tuyau. Vous pouvez également extraire des clés dans la propriété helper et l’utiliser:
@Component({
selector: 'my-app',
providers: [],
template: `
<div>
<select>
<option *ngFor="let key of keys" [value]="key" [label]="countries[key]"></option>
</select>
</div>
`,
directives: []
})
export class App {
countries = CountryCodeEnum
constructor() {
this.keys = Object.keys(this.countries).filter(Number)
}
}
Voici un moyen très simple pour Angular2 v2.0.0. Par souci d’exhaustivité, j’ai inclus un exemple de définition d’une valeur par défaut de country
select via formes réactives .
@Component({
selector: 'my-app',
providers: [],
template: `
<div>
<select id="country" formControlName="country">
<option *ngFor="let key of keys" [value]="key">{{countries[key]}}</option>
</select>
</div>
`,
directives: []
})
export class App {
keys: any[];
countries = CountryCodeEnum;
constructor(private fb: FormBuilder) {
this.keys = Object.keys(this.countries).filter(Number);
this.country = CountryCodeEnum.Belgium; //Default the value
}
}
J'ai préféré disposer d'une fonction utilitaire simple partagée sur mon Angular App, pour convertir la enum
en un tableau standard afin de générer la sélection:
export function enumSelector(definition) {
return Object.keys(definition)
.map(key => ({ value: definition[key], title: key }));
}
remplir une variable dans le composant avec:
public countries = enumSelector(CountryCodeEnum);
puis remplissez ma sélection de matériaux en tant qu'anciennes bases basées sur un tableau:
<md-select placeholder="Country" [(ngModel)]="country" name="country">
<md-option *ngFor="let c of countries" [value]="c.value">
{{ c.title }}
</md-option>
</md-select>
Merci pour ce fil!
Une autre solution similaire, qui n'omette pas "0" (comme "Unset"). Utilisation du filtre (nombre) IMHO n'est pas une bonne approche.
@Component({
selector: 'my-app',
providers: [],
template: `
<select>
<option *ngFor="let key of keys" [value]="key" [label]="countries[key]"></option>
</select>`,
directives: []
})
export class App {
countries = CountryCodeEnum;
constructor() {
this.keys = Object.keys(this.countries).filter(f => !isNaN(Number(f)));
}
}
// ** NOTE: This enum contains 0 index **
export enum CountryCodeEnum {
Unset = 0,
US = 1,
EU = 2
}
À partir de Angular 6.1 et supérieur, vous pouvez utiliser le KeyValuePipe
intégré comme ci-dessous (collé à partir de documents angular.io).
Je suppose qu’une énumération contient bien sûr des chaînes lisibles par des êtres humains :)
@Component({
selector: 'keyvalue-pipe',
template: `<span>
<p>Object</p>
<div *ngFor="let item of object | keyvalue">
{{item.key}}:{{item.value}}
</div>
<p>Map</p>
<div *ngFor="let item of map | keyvalue">
{{item.key}}:{{item.value}}
</div>
</span>`
})
export class KeyValuePipeComponent {
object: {[key: number]: string} = {2: 'foo', 1: 'bar'};
map = new Map([[2, 'foo'], [1, 'bar']]);
}
Une autre conséquence de cette réponse, mais cela mappe en réalité les valeurs sous forme de nombres, au lieu de les convertir en chaînes, ce qui est un bogue. Cela fonctionne aussi avec 0 enums basés
@Component({
selector: 'my-app',
providers: [],
template: `
<select>
<option *ngFor="let key of keys" [value]="key" [label]="countries[key]"></option>
</select>`,
directives: []
})
export class App {
countries = CountryCodeEnum;
constructor() {
this.keys = Object.keys(this.countries)
.filter(f => !isNaN(Number(f)))
.map(k => parseInt(k));;
}
}
Avec des énumérations de chaîne, vous pouvez essayer ceci.
Mon enum string a la définition suivante:
enum StatusEnum {
Published = <any> 'published',
Draft = <any> 'draft'
}
et traduit en js de la manière suivante:
{
Published: "published",
published: "Published",
Draft: "draft",
draft: "Draft"
}
J'ai quelques-uns de ceux-ci dans mon projet, donc créé une petite fonction d'assistance dans une bibliothèque de services partagés:
@Injectable()
export class UtilsService {
stringEnumToKeyValue(stringEnum) {
const keyValue = [];
const keys = Object.keys(stringEnum).filter((value, index) => {
return !(index % 2);
});
for (const k of keys) {
keyValue.Push({key: k, value: stringEnum[k]});
}
return keyValue;
}
}
Init dans le constructeur de votre composant et le lier à votre modèle comme ceci:
En composant:
statusSelect;
constructor(private utils: UtilsService) {
this.statusSelect = this.utils.stringEnumToKeyValue(StatusEnum);
}
Dans le modèle:
<option *ngFor="let status of statusSelect" [value]="status.value">
{{status.key}}
</option>
N'oubliez pas d'ajouter UtilsService au tableau de fournisseurs dans votre app.module.ts afin de pouvoir l'injecter facilement dans différents composants.
Je suis un débutant en TypeScript, donc corrigez-moi si je me trompe ou s'il existe de meilleures solutions.
C'est la meilleure option que vous pouvez appliquer sans aucun tuyau ni code supplémentaire.
import { Component } from '@angular/core';
enum AgentStatus {
available =1 ,
busy = 2,
away = 3,
offline = 0
}
@Component({
selector: 'my-app',
template: `
<h1>Choose Value</h1>
<select (change)="parseValue($event.target.value)">
<option>--select--</option>
<option *ngFor="let name of options"
[value]="name">{{name}}</option>
</select>
<h1 [hidden]="myValue == null">
You entered {{AgentStatus[myValue]}}
</h1>`
})
export class AppComponent {
options : string[];
myValue: AgentStatus;
AgentStatus : typeof AgentStatus = AgentStatus;
ngOnInit() {
var x = AgentStatus;
var options = Object.keys(AgentStatus);
this.options = options.slice(options.length / 2);
}
parseValue(value : string) {
this.myValue = AgentStatus[value];
}
}