Typescript 基于Angular2中的枚举进行选择

Typescript 基于Angular2中的枚举进行选择,typescript,angular,angular2-forms,Typescript,Angular,Angular2 Forms,我有这个枚举(我使用的是TypeScript): 我想在我的表单中构建一个select,每个选项的值为枚举整数值,标签为枚举文本,如下所示: <select> <option value="1">France</option> <option value="2">Belgium</option> </select> 法国 比利时 如何执行此操作?通过创建数组来简化更新2 @Pipe({name:'e

我有这个枚举(我使用的是TypeScript):

我想在我的表单中构建一个select,每个选项的值为枚举整数值,标签为枚举文本,如下所示:

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

法国
比利时

如何执行此操作?

通过创建数组来简化更新2

@Pipe({name:'enumToArray'})
导出类EnumToArraype实现PipeTransform{
变换(值):对象{
返回对象.keys(value).filter(e=>!isNaN(+e)).map(o=>{return{index:+o,name:value[o]});
}
}
@组成部分({
...
导入:[枚举数组类型],
模板:`{item.index}}:{{item.name}`
})
类MyComponent{
角色=角色;
}
更新

而不是
管道:[KeysPipe]

使用

@NgModule({
声明:[KeysPipe],
导出:[密钥管道],
}
导出类SharedModule{}
@NgModule({
...
导入:[共享模块],
})
原创

使用管道中的

我不得不对管道进行一些修改,使其能够与枚举一起正常工作 (另见)

@Pipe({name:'keys})
导出类keypipe实现PipeTransform{
转换(值,参数:字符串[]):任意{
让键=[];
for(值中的变量枚举成员){
如果(!isNaN(parseInt(枚举成员,10))){
push({key:enumMember,value:value[enumMember]});
//如果需要日志,请取消注释
//log(“枚举成员:”,值[enumMember]);
} 
}
返回键;
}
}
@组件({。。。
管道:[键管道],
模板:`
{{item.value}}
`
})
类MyComponent{
国家=CountryCodeEnum;
}


如果不想创建新管道,请参见另一个解决方案。您还可以将关键点提取到helper属性中并使用它:

@组件({
选择器:“我的应用程序”,
提供者:[],
模板:`
`,
指令:[]
})
导出类应用程序{
countries=CountryCodeEnum
构造函数(){
this.keys=Object.keys(this.countries).filter(k=>!isNaN(Number(k));
}
}
演示:

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];

  }
}
编辑:

如果需要将选项设置为数字而不是字符串:

  • [value]
    替换为
    [ngValue]
  • 之后添加
    .map(Number)
    。过滤器(…)

    • 对于Angular2 v2.0.0,这里有一个非常简单的方法。为了完整起见,我提供了一个设置国家默认值的示例

      @组件({
      选择器:“我的应用程序”,
      提供者:[],
      模板:`
      {{国家[关键]}
      `,
      指令:[]
      })
      导出类应用程序{
      密钥:任意[];
      国家=CountryCodeEnum;
      构造函数(私有fb:FormBuilder){
      this.keys=Object.keys(this.countries).filter(Number);
      this.country=CountryCodeEnum.Belgium;//默认值
      }
      }
      
      我更喜欢在我的Angular应用程序中共享一个简单的实用程序函数,将
      枚举
      转换为标准数组以构建选择:

      export function enumSelector(definition) {
        return Object.keys(definition)
          .map(key => ({ value: definition[key], title: key }));
      }
      
      要在组件中填充变量,请执行以下操作:

      public countries = enumSelector(CountryCodeEnum);
      
      然后填充我的材质,选择作为基于阵列的旧材质:

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

      感谢您提供此线程!

      另一个类似的解决方案,不会忽略“0”(如“Unset”)。使用筛选器(数字)IMHO不是一个好方法

      @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
      }
      
      @组件({
      选择器:“我的应用程序”,
      提供者:[],
      模板:`
      `,
      指令:[]
      })
      导出类应用程序{
      国家=CountryCodeEnum;
      构造函数(){
      this.keys=Object.keys(this.countries).filter(f=>!isNaN(Number(f));
      }
      }
      //**注意:此枚举包含0个索引**
      导出枚举CountryCodeEnum{
      Unset=0,
      US=1,
      欧盟=2
      }
      
      使用字符串枚举,您可以尝试此操作

      我的字符串枚举具有以下定义:

          enum StatusEnum {
              Published = <any> 'published',
              Draft = <any> 'draft'
          }
      
      我在我的项目中有一些这样的功能,因此在共享服务库中创建了小助手函数:

         @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;
             }
         }
      
      在组件构造函数中初始化并将其绑定到模板,如下所示:

      在组件中:

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

          <option *ngFor="let status of statusSelect" [value]="status.value">
              {{status.key}}
          </option>
      
      
      {{status.key}}
      
      不要忘记将UtilsService添加到app.module.ts中的提供程序阵列中,以便您可以轻松地将其插入不同的组件中


      我是一个typescript新手,所以如果我错了或者有更好的解决方案,请纠正我。

      这个答案的另一个派生,但这实际上将值映射为数字,而不是将它们转换为字符串,这是一个bug。它也适用于基于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));;
        }
      }
      
      @组件({
      选择器:“我的应用程序”,
      提供者:[],
      模板:`
      `,
      指令:[]
      })
      导出类应用程序{
      国家=CountryCodeEnum;
      构造函数(){
      this.keys=Object.keys(this.countries)
      .filter(f=>!isNaN(数字(f)))
      .map(k=>parseInt(k));;
      }
      }
      
      从Angular 6.1及更高版本开始,您可以使用内置的
      KeyValuePipe
      如下所示(从Angular.io文档粘贴)

      我假设枚举包含人类友好的可读字符串(当然:)

      @组件({
      选择器:“keyvalue管道”,
      模板:`
      反对

      {{item.key}}:{{item.value} 地图

      {{item.key}}:{{item.value} ` }) 导出类KeyValuePipeComponent{ 对象:{[key:number]:string}={2:foo',1:bar'}; 地图=新地图([[2,'foo'],[1,'bar']]);
      }
      这是您无需任何管道或额外代码即可应用的最佳选项。

      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];
      
        }
      }
      
      从'@angular/core'导入{Component};
      枚举代理状态{
      可用=1,
      忙=2,
      客场=3,
      离线=0
      }
      @组成部分({
      选择器:“我的应用程序”,
      模板:`
      选择值
      --挑选--
      {{name}}
      您输入了{{AgentStatus[myValue]}
      `
      })
      导出类AppComponent{
      选项:字符串[];
      myValue:AgentStatus;
      代理状态:股份公司类型
      
      @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));;
        }
      }
      
      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];
      
        }
      }
      
       enum Test {
         No,
         Pipe,
         Needed,
         Just,
         Use,
         Filter
       }
      
       console.log('Labels: ');
       let i = 0;
       const selectOptions = [
          ];
       Object.keys(Test).filter(key => !Number(key) && key !== '0').forEach(key => {
          selectOptions.push({position: i, text: key});
          i++;
        });
       console.log(selectOptions);
      
      Console:
      Labels: 
          (6) [{…}, {…}, {…}, {…}, {…}, {…}]
          0: {position: 0, text: "No"}
          1: {position: 1, text: "Pipe"}
          2: {position: 2, text: "Needed"}
          3: {position: 3, text: "Just"}
          4: {position: 4, text: "Use"}
          5: {position: 5, text: "Filter"}
      
      export enum Unit
      {
          Kg = 1,
          Pack,
          Piece,
          Litre
      }
      
      import { Pipe, PipeTransform } from '@angular/core';
      
      @Pipe({
        name: 'enumToArray'
      })
      export class EnumToArrayPipe implements PipeTransform {
      
        transform(enumObj: Object) {
      
          const keys = Object.keys(enumObj).filter(key => parseInt(key));
          let map = new Map<string, string>();
          keys.forEach(key => map.set(key, enumObj[key]))
          console.log( Array.from(map));
          return Array.from(map);
        }
      
      }
      
          import { Pipe, PipeTransform } from '@angular/core';
      
          @Pipe({
            name: 'enumToArray'
          })
          export class EnumToArrayPipe implements PipeTransform {
      
            transform(enumObj: Object) {
      
              const keys = Object.keys(enumObj).filter(key => parseInt(key));
              let set = new Set();
              keys.forEach(key => set.add({ key: parseInt(key), value: enumObj[key] }))
              return Array.from(set);
            }
      
          }