Domanda Seleziona in base a enum in Angular2


Ho questo enum (sto usando Dattiloscritto):

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

Mi piacerebbe costruire un selezionare nel mio modulo, con per ciascuno opzione il valore intero enum come valore e il testo enum come etichetta, come questo:

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

Come posso fare questo ?


44
2018-03-02 14:30


origine


risposte:


aggiornare

invece di pipes: [KeysPipe]

uso

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

originale

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

Ho dovuto modificare un po 'la pipa per farlo funzionare correttamente con le enumerazioni (Guarda anche Come si ottengono i nomi delle voci enum di TypeScript?)

@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

Guarda anche Come usare * ngFor con Object?


34
2018-03-02 14:38



Un'altra soluzione se non vuoi creare una nuova pipa. Puoi anche estrarre le chiavi nella proprietà helper e usarla:

@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


37
2018-03-02 15:11



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 forme reattive.

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

15
2017-09-30 04:14



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
}

5
2017-09-05 09:06



Ho preferito avere una semplice funzione di utilità condivisa attraverso la mia Angular 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 nel componente con:

public countries = enumSelector(CountryCodeEnum);

e quindi riempire il mio materiale Select come miei vecchi array based:

<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!


4
2017-08-11 17:44



Con enumerazione delle stringhe puoi provarlo.

La mia stringa enum ha la seguente definizione:

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

e si traduce in js nel modo seguente:

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

Ne ho alcuni di questi nel mio progetto, quindi ho creato una piccola funzione di supporto in una lib di servizi condivisi:

   @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 costruttore del componente e Legalo al modello in questo modo:

Nel componente:

    statusSelect;

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

Nel modello:

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

Non dimenticare di aggiungere UtilsService all'array del provider nel tuo app.module.ts in modo da poterlo facilmente inserire in diversi componenti.

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


0
2017-11-05 07:51



Un altro spin off di questa risposta, ma in realtà questo mappa i valori come numeri, invece di convertirli in stringhe che sono un bug. Funziona anche con le enumerazioni basate su 0

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

0
2018-04-11 10:58