【问题标题】:Don't know how to implement an enum using an interface in an angular2 class不知道如何使用 angular2 类中的接口实现枚举
【发布时间】:2017-09-08 14:50:32
【问题描述】:

在这里转圈。对 Typescript 来说非常新,它在琐碎的实现中引起了很大的麻烦。

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

Microsoft Visual Studio Code 在第 21 行出现问题,其中类型 '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;    
    //   }
}

比较 这个实现满足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;    
    }
}

【问题讨论】:

    标签: typescript angular angular2-services angular2-forms


    【解决方案1】:

    在这里你想要什么并不明显,但让我解释一些事情......

    我创建了一篇讨论这个的博客文章:
    How to use TypeScript Enums, especially with Angular 2+
    但我会在这里包含所有内联信息:

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

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

    键入的好处在枚举中非常有限。

    此行有效:

    var value = <AgentStatus>"offline";
    

    但这没什么用,因为

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

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

    如何将字符串转换为枚举

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

    这使得之前的比较工作:

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

    现在,还有几个问题:

    如何获得等效的字符串?

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

    遇到问题

    如果你在你的模板中写这个:

    {{AgentStatus[myValue]}}
    

    它会失败,因为它无法访问导入的类型(它稍后会被 Angular 执行)。

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

    export class MyComponent {
        // allows you to use AgentStatus in template
        AgentStatus = AgentStatus;        
    
        myValue : AgentStatus;
        // ...
    }
    

    可运行演示

    这是一个解释我在此处指出的所有内容的示例:

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

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

    【讨论】:

      【解决方案2】:

      Microsoft Visual Studio Code 在第 21 行出现问题,其中类型“typeof AgentStatus”不可分配给类型“AgentStatus”...为什么

      你有states:AgentStatus = AgentStatus。这里states:AgentStatus 实际上是AgentStatus 类型的值,而= AngentStatus整个枚举

      修复

      你可能想要:

      states:typeof AgentStatus = AgentStatus
      

      或者

      states:AgentStatus = AgentStatus.Available
      

      更多

      这类似于您尝试分配foo:SomeClass = SomeClass 而不是foo:SomeClass = new SomeClass()

      【讨论】:

      • 谢谢,我根据您的建议更新了问题。现在得到一个令人难以置信的神秘错误。不过,Tscript 似乎很高兴。 browser_adapter.ts:78EXCEPTION:错误:未捕获(在承诺中):TypeError:无法读取 null 的属性“isSkipSelf”
      猜你喜欢
      • 1970-01-01
      • 2020-11-28
      • 1970-01-01
      • 2013-05-11
      • 2019-06-03
      • 1970-01-01
      • 2010-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多