2016年11月15日 星期二

[Angular] dropdown list with ngFor and enum

 Angular    dropdown    select/options    ngFor    enum


Introduction


The article will show how to use ngFor, ngModel and enum to create a dropdown list (select/options).


Environment

angular 2: 2.1.0



select/options


HTML

<select class="form-control"
[(ngModel)]="selectedProdType"
(ngModelChange)="changeSelectedType($event)">
   <option *ngFor="let type of prodTypes" [ngValue]="type">{{type.name}}</option>
</select>

Notice that ngValue will affect the value bind to ngModel and the parameter: $event of ngModelChange.

[ngValue]= "type" , selectedProdType will be the selected object.
[ngValue]= "type.id" , selectedProdType will be the id of the selected object.



Typescript

/// <reference path="../../../lib-npm/typings/jsnlog.d.ts" />
import {Component, OnInit} from '@angular/core';
import {ProductTypeEnum} from '../../enum/ProductTypeEnum';

@Component({
    selector: 'product-create',
})

export class ProductCreateComponent {
    title: string;
    private selectedProdType: ProductType;
    private prodTypes: ProductType[];

    constructor() {
        this.prodTypes = PRODUCT_TYPES;
    }

    //Change Selected Product type callback
   private changeSelectedType(event: any) {
       console.log(event); //object, depends on ngValue
       console.log(this.selectedProdType); //object, depends on ngValue
    }
}

const PRODUCT_TYPES: any[] =
    [{ "id": "1", "name": "Book" }, { "id": "2", "name": "Toy" }, { "id": "3", "name": "Music" }];



Result




Use enum as the data source


If the options of the dropdown list are constant, we can store them in an enum.


Typescript : enum

export enum ProductTypeEnum {
    Book = 1,
    Toy,
    Music
}


Typescript : Convert enum to array

First we create a static function for reading all the elements in ProductTypeEnum and convert them to a name-value-pair array.

export class EnumEx {
    static getNamesAndValues<T extends number>(e: any) {
        return EnumEx.getNames(e).map(n => ({ name: n, value: e[n] as T }));
    }
}



Then we can refactor the original component.ts like this.

constructor() {
    this.prodTypes = this.getProductTypes();
}

//Get Product types list
public getProductTypes() {
    let prodTypes: ProductType[] = [];

    //Get name-value pairs from ProductTypeEnum
    let prodTypeEnumList = EnumEx.getNamesAndValues(ProductTypeEnum);

    //Convert name-value pairs to ProductType[]
    prodTypeEnumList.forEach(pair => {
        let prodType = { 'id': pair.value.toString(), 'name': pair.name };
        prodTypes.push(prodType);
    });

    return prodTypes;
}



Furthermore


Since we have enum for the select options, we can use it for comparing or so.

private changeSelectedType(event: any) {
    switch (event.id)
    {
        case ProductTypeEnum.Book.toString():
            //...
            break;
        case ProductTypeEnum.Toy.toString():
            //...
            break;
        case ProductTypeEnum.Music.toString():
            //...
            break;
        default:
            break;
    }
}


Reference


2 則留言: