2016-03-02 21 views
38

ho questo enum (sto usando dattiloscritto):selezione basata su enum in Angular2

export enum CountryCodeEnum { 
    France = 1, 
    Belgium = 2 
} 

Vorrei costruire un selezionare nel mio modulo, con per ogni opzione il valore intero enum come valore, e il testo enum come etichetta, in questo modo:

<select> 
    <option value="1">France</option> 
    <option value="2">Belgium</option> 
</select> 

come posso fare questo?

risposta

29

aggiornamento

anziché pipes: [KeysPipe]

uso

@NgModule({ 
    declarations: [KeysPipe], 
    exports: [KeysPipe], 
} 
export class SharedModule{} 
@NgModule({ 
    ... 
    imports: [SharedModule], 
}) 

originale

Utilizzando il tubo keys da https://stackoverflow.com/a/35536052/217408

ho dovuto modificare il tubo un po 'per farlo funzionare correttamente con le enumerazioni (vedi anche How does one get the names of TypeScript enum entries?)

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

Plunker

Vedi anche How to use *ngFor with Object?

+1

Aggiungerò ancora una modifica nell'associazione per lavorare keys.push ({chiave: parseInt (enumMember, 10), value: value [enumMember]}); – Mihail

29

Un'altra soluzione se non si desidera creare una nuova pipa. Si potrebbe anche estrarre le chiavi in ​​proprietà aiutante e usarlo:

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

Demo:http://plnkr.co/edit/CMFt6Zl7lLYgnHoKKa4E?p=preview

+1

Non ho visto l'etichetta nel menu a discesa, quindi ho modificato la riga delle opzioni su: '' ' '' ' –

+16

Se il tuo enum inizia con 0 non funzionerà. È meglio usare: Object.keys (CountryCodeEnum) .filter (k =>! IsNaN (Number (k))); – Oleg

+0

Se enum inizia con 0, questo è un approccio negativo. Se Object.keys (this.countries) restituisce ["0", "1", "2", "NotSet", "EU", "US"], il filtro ometterà "0", quindi il risultato filtrato sarà ["1", "2"]. Non ["0", "1", "2"] come mi aspetterei. – Tomino

15

Ecco un modo molto semplice per Angular2 v2.0.0. Per completezza, ho incluso un esempio di impostazione di un valore predefinito di country selezionare tramite reactive forms.

@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 
    } 
} 
+0

È necessario filtrare metà dei valori come ** dfsq ** suggerito: Object.keys (this.countries) .filter (Number); – AFD

+0

yup buona cattura. Aggiornato. – rynop

+0

Se enum inizia con 0, questo è un approccio errato. Se Object.keys (this.countries) restituisce ["0", "1", "2", "NotSet", "EU", "US"], il filtro ometterà "0", quindi il risultato filtrato sarà ["1", "2"]. Non ["0", "1", "2"] come mi aspetterei. – Tomino

1

ho preferito avere una semplice funzione di utilità condivisa in tutta la mia angolare App, per convertire il enum in una matrice standard per costruire seleziona:

export function enumSelector(definition) { 
    return Object.keys(definition) 
    .map(key => ({ value: definition[key], title: key })); 
} 

per riempire una variabile nella componente con :

public countries = enumSelector(CountryCodeEnum); 

e quindi riempire il mio materiale Selezionare come i miei vecchi quelli a base di matrice:

<md-select placeholder="Country" [(ngModel)]="country" name="country"> 
    <md-option *ngFor="let c of countries" [value]="c.value"> 
    {{ c.title }} 
    </md-option> 
</md-select> 

Grazie per questa discussione!

+0

Che aspetto ha il tuo CountryCodeEnum? – phhbr

+0

@phhbr Penso che ho usato valori non numerici, come: '' 'esportazione enum CountryCodeEnum { Francia = '1', Belgio = '2' } ' '' –

+0

L'oggetto del CountryCodeEnum sembra qualcosa di simile quando si utilizza il vostro enum: [ 1: "la Francia", 2: "Belgio", Francia: 1, Non definito: 2, ] – phhbr

4

Un'altra soluzione simile, che non omette "0" (come "Unset"). Utilizzo del filtro (numero) IMHO non è un buon approccio.

@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 
} 
+0

Grazie mille! questo ha aiutato – Bellash

0

Con enumerazioni di stringhe puoi provare questo.

mio enum stringa ha la seguente definizione:

enum StatusEnum { 
     Published = <any> 'published', 
     Draft = <any> 'draft' 
    } 

e si traduce in js nel seguente modo:

{ 
     Published: "published", 
     published: "Published", 
     Draft: "draft", 
     draft: "Draft" 
    } 

ho un paio di questi nel mio progetto così creato la funzione piccolo aiuto nella un servizio condiviso lib:

@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 nel tuo componente constructor e Bi ND al vostro modello come questo:

In componente:

statusSelect; 

    constructor(private utils: UtilsService) { 
     this.statusSelect = this.utils.stringEnumToKeyValue(StatusEnum); 
    } 

in Template:

<option *ngFor="let status of statusSelect" [value]="status.value"> 
     {{status.key}} 
    </option> 

Non dimenticare di aggiungere l'UtilsService alla matrice fornitore nel vostro app.module. così puoi facilmente iniettarlo in diversi componenti.

Sono un principiante dattiloscritto quindi per favore correggimi se sbaglio o se ci sono soluzioni migliori.

Problemi correlati