不知道如何使用angular2类中的接口实现枚举 [英] Don't know how to implement an enum using an interface in an angular2 class

查看:139
本文介绍了不知道如何使用angular2类中的接口实现枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这里转圈.对于Typescript来说是非常新的东西,它在琐碎的实现上引起了严重的头痛.

Going around in circles here. Very new to Typescript and it's causing major headaches with trivial implementations.

如何在AgentStatusService中定义它应该具有称为['offline','available','busy','away']的4个选项组成的数组?定义了AgentStatus(或者是?),然后将其注入到AgentStatusService中.

How do a define in AgentStatusService that it should have an array of 4 options called ['offline','available','busy','away'] ? AgentStatus is defined ( or is it? ) and I am injecting it into the AgentStatusService.

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

Microsoft Visual Studio Code is barfing on line 21 where the type 'typeof AgentStatus' is not assignable to type 'AgentStatus'... why?

已更新:

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;    
    //   }
}

比较 此实现满足angular2:

Compare with This implementation satisfies 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;    
    }
}

推荐答案

您在这里想要的东西并不明显,但让我解释一些事情...

It's not obvious what you want here, but let me explain a few things...

我创建了一篇有关此问题的博客文章:
如何使用TypeScript枚举,尤其是Angular 2+
但我将在此内联所有信息:

I have created a blog post talking about this:
How to use TypeScript Enums, especially with Angular 2+
But I'll include all the information inline here:

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

A enum is just an object. Your enum is written something like this in JavaScript:

{
    0: "offline",
    1: "available",
    2: "busy",
    3: "away",
    available: 1,
    busy: 2,
    away: 3,
    offline: 0
}

枚举带来的好处非常有限.

The benefit from typing is very limited in enums.

此行有效:

var value = <AgentStatus>"offline";

但这没用,因为

value == AgentStatus.offline // <- false, because it's "offline" == 0

因此,您应该始终将数值存储为数字,您可以通过以下方式获得这些信息:

So, you should always store your values as numbers, which you can obtain as follows:

如何将字符串转换为枚举

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

这使得之前的比较工作有效:

This makes the previous comparison work:

value == AgentStatus.offline // <- true, because it's 0 == 0

现在,仍然有几个问题:

Now, a couple questions remain:

如何获取等效字符串?

AgentStatus.offline // 0
AgentStatus[AgentStatus.offline] // -> AgentStatus[0] -> "offline"

如何获取所有可能的枚举值?

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

Gotcha

如果您在模板中编写此代码:

If you write this in your template:

{{AgentStatus[myValue]}}

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

It will fail, because it doesn't have access to imported types (it gets executed later by Angular).

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

To make it work, your component will need to have a reference to the enum type / object, something like:

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

    myValue : AgentStatus;
    // ...
}

可运行的演示

以下是一个示例,解释了我在此处指出的所有内容:

Here is an example that explains everything I pointed in here:

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

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

这篇关于不知道如何使用angular2类中的接口实现枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆