不知道如何使用angular2类中的接口实现枚举

Sim*_*mon 8 typescript angular2-forms angular2-services angular

在这里绕圈子.对Typescript来说是一个新手,它引起了一些令人头疼的琐碎实现.

如何定义AgentStatusService它应该有一个名为4个选项的数组['offline','available','busy','away']?AgentStatus是定义的(或者是?),我将它注入到AgentStatusService.

Microsoft Visual Studio Code在第21行进行了barfing,其中类型'typeof AgentStatus'不能分配给'AgentStatus'类型...为什么?

更新:

import { EventEmitter, Injectable } from '@angular/core';

export enum AgentStatus {
    available =1 ,
    busy = 2,
    away = 3,
    offline = 0
}

export interface IAgentStatusService {
    state: number
    states: AgentStatus
}
@Injectable()
export class AgentStatusService implements IAgentStatusService {

    state:number;  // this really should be string, but line 22 returns a number
    states:AgentStatus;

    constructor(states:typeof AgentStatus = AgentStatus){
        // unreacheable code browser_adapter.ts:78EXCEPTION: Error: Uncaught (in promise): TypeError: Cannot read property 'isSkipSelf' of null
        // absolutely impossible to debug...
        this.state = AgentStatus.offline // this returns a number
    }

    //   set state(state:string){
    //       try{
    //       this._state = this.states[state];
    //       // string 


    //       } catch(e){
    //           console.log('tried setting bad enum value on AgentStatus', e.stack);
    //       }
    //   }

    //   get state():string{
    //       return this._state; 
    //   }

    //   get model():any {
    //     return this.states;    
    //   }
}
Run Code Online (Sandbox Code Playgroud)

比较 此实现满足angular2:

@Injectable()
export class AgentStatusService {
    public states = ['offline','available','busy','away'];
    private _state;

    constructor(){
        this._state = this.states[0];
    }

    set state(state:string){
        try{
        this._state = this.states[state];
        } catch(e){
            console.log('tried setting bad enum value on AgentStatus', e.stack);
        }
    }

    get state():string{
        return this._state; 
    }

    get model():any {
        return this.states;    
    }
}
Run Code Online (Sandbox Code Playgroud)

Mel*_*igy 15

你在这里想要的并不明显,但让我解释一下......

我创建了一篇博客文章,讨论了这个问题:
如何使用TypeScript Enums,特别是使用Angular 2+
但是我将在这里包含所有内联信息:

枚举只是一个对象.你的枚举在JavaScript中写得像这样:

{
    0: "offline",
    1: "available",
    2: "busy",
    3: "away",
    available: 1,
    busy: 2,
    away: 3,
    offline: 0
}
Run Code Online (Sandbox Code Playgroud)

在枚举中打字的好处非常有限.

此行有效:

var value = <AgentStatus>"offline";
Run Code Online (Sandbox Code Playgroud)

但它没用,因为

value == AgentStatus.offline // <- false, because it's "offline" == 0
Run Code Online (Sandbox Code Playgroud)

因此,您应始终将值存储为数字,您可以按如下方式获取这些数字:

如何将字符串转换为枚举

var value = AgentStatus["offline"]; // so value is now 0

// You can also use this, which only gives IDE hints, no runtime benefit
var value: AgentStatus = AgentStatus["offline"];
Run Code Online (Sandbox Code Playgroud)

这使得之前的比较工作:

value == AgentStatus.offline // <- true, because it's 0 == 0
Run Code Online (Sandbox Code Playgroud)

现在,还有几个问题:

你如何得到相当于字符串的字符串?

AgentStatus.offline // 0
AgentStatus[AgentStatus.offline] // -> AgentStatus[0] -> "offline"
Run Code Online (Sandbox Code Playgroud)

你如何得到所有可能的枚举值?

var options : string[] = Object.keys(AgentStatus);
// The options list has the numeric keys, followed by the string keys
// So, the first half is numeric, the 2nd half is strings
options = options.slice(options.length / 2);
Run Code Online (Sandbox Code Playgroud)

疑难杂症

如果你在模板中写这个:

{{AgentStatus[myValue]}}
Run Code Online (Sandbox Code Playgroud)

它将失败,因为它无法访问导入的类型(稍后由Angular执行).

要使其工作,您的组件将需要引用枚举类型/对象,例如:

export class MyComponent {
    // allows you to use AgentStatus in template
    AgentStatus = AgentStatus;        

    myValue : AgentStatus;
    // ...
}
Run Code Online (Sandbox Code Playgroud)

Runnable演示

这是一个例子,解释了我在这里指出的一切:

http://plnkr.co/edit/vOeeDrCI6CmsXdWaMtwG?p=preview

查看文件:app/app.component.ts.