Angular Enum 要如何轉換為下拉選單

Angular Enum Dropdownlist

今天來談談 Angular 開發的一些大小事,相信程式開發的朋友們常常會用到 Enum 這種型別,中文翻譯為列舉,簡單講就是列出集合中物件的型別,例如星期的列舉值為 SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY、SATURDAY ,但是如何將列舉轉換為下拉選單呢,今天就來跟大家談談這問題。

前幾日參加了 Angular Taiwan 的論壇讓筆者受益良多當下的筆記放在 Angular Taiwan論壇筆記 ,然後想起筆者一年前開發 Angular 時遇到一些開發上的問題,想說兩年後來找找是否有更容易解決的方案,今天就跟大家分享一下這個問題以及解決當方法。

列舉

在說明解決方法之前先跟大家說明一下問題,在說明問題之前當然需要跟大家說明列舉這個東西,在 typescript 中可以定義enum關鍵字,完整的內容如下:

enum Currency {
    USD = 'US Dollar',
    MYR = 'Malaysian Ringgit',
    SGD = 'Singapore Dollar',
    INR = 'Indian Rupee',
    JPY = 'Japanese Yen'
}

列舉這東西可以定義星期、幣別等等的內容,並且可以讓使用者選取列舉種中的一或是多個項目,就以要使用者選取一個項目而言它是非常適合放在下拉選單之中,然而在所有東西都是 object 的 javascript 中列舉是怎麼產生出來的,其實就是在編譯typescript時將列舉轉換成以下內容:

var Currency;
(function (Currency) {
    Currency["USD"] = "US Dollar";
    Currency["MYR"] = "Malaysian Ringgit";
    Currency["SGD"] = "Singapore Dollar";
    Currency["INR"] = "Indian Rupee";
    Currency["JPY"] = "Japanese Yen";
})(Currency = exports.Currency || (exports.Currency = {}));

這邊讀者們可以試試 Typescript Playground 這 typescript 官方轉譯網站來將 typescript 轉譯成 javascript 的內容。然而在 Angular 中如何將列舉值中所有的元素都列出來呢,這則是我們今天要聊的話題。

Angular 6+的解法

在Angular 6時新增了一個 pipe ,叫做 keyvalue 就是專門將元素中的 keyvalue 取出來,說到這邊讀者們應該能體會到,阿這就是我們要的東西了,所以透過 keyvalue 我們可以在 template 內用以下的方法將下拉選單給呈現出來:

<select [(ngModel)]="selectedCurrency">
    <option
        *ngFor="let currency of currencies | keyvalue" 
        value="{{currency.key}}">
            {{currency.value}}
    </option>
</select>

然而在 component.ts 中用下列的內容定義,就可以將選定的值動態綁定到 selectedCurrency 中:

export class AppComponent {
    currencies = Currency;
    selectedCurrency: Currency;
}

如此就可以完成將 enum 轉換成下拉選單了。

在 Angular 6之前呢

這個問題的解法很簡單,就是升級到 Angular 6 以上就可以了,因為 Angular 6 的升級有工具可以自動化檢測、更新,所以升級 Angular 是不困難的,但是如果真的不願意升級的話可以透過自訂 pipe 來完成,簡單就是先輸入以下指令:

$ ng generate pipe MapToIterable

然後將 .pipe.ts 的內容置換成以下內容即可:

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
  name: 'mapToIterable'
})
export class MapToIterable implements PipeTransform {
  transform(v: any, args?: any): any {
    return Object.keys(v).map(k => {
      return {
        key: k,
        value: v[k]
      };
    });
  }
}

使用方法就是將上列的 template keyvalue 部分改為 mapToIterable 即可,如下列所示:

<select [(ngModel)]="selectedCurrency">
    <option
        *ngFor="let currency of currencies | mapToIterable" 
        value="{{currency.key}}">
            {{currency.value}}
    </option>
</select>

如此不論讀者們用的 Angular 是6之前還是6之後都可以簡單將 Enum 轉換為下拉選單了。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *