2016-05-24 18 views
7

Qui intorno cerchi in cerchio. Molto nuovo a Typescript e causa grossi grattacapi con implementazioni banali.Non so come implementare un enum utilizzando un'interfaccia in una classe angular2

Come definire in AgentStatusService che dovrebbe disporre di una matrice di 4 opzioni denominate ['offline','available','busy','away']? AgentStatus è definito (o è?) E lo sto iniettando nello AgentStatusService.

Microsoft Visual Studio Code è un bar sulla riga 21 in cui il tipo "typeof AgentStatus" non è assegnabile al tipo "AgentStatus" ... perché?

Aggiornato:

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

Confronta con Questo soddisfa implementazione 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;  
    } 
} 

risposta

12

Non è ovvio ciò che si vuole qui, ma mi permetta di spiegare alcune cose ...

ho creato un post a parlare di questo:
How to use TypeScript Enums, especially with Angular 2+
ma io includono tutte le informazioni in linea qui:

Un enum è solo un oggetto. Il tuo enum è scritto qualcosa di simile in JavaScript:

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

Il beneficio dalla digitazione è molto limitata nella enumerazioni.

Questa linea è valida:

var value = <AgentStatus>"offline"; 

Ma non è utile, perché

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

Quindi, si dovrebbe sempre memorizzare i valori come numeri, che si possono ottenere i seguenti:

Come convertire stringa in enum

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

Questo rende il precedente lavoro di confronto:

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

Ora, un paio di domande rimangono:

Come si ottiene l'equivalente di stringa?

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

Come si ottiene tutti i possibili valori enum?

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

Se si scrive questo nel vostro modello:

{{AgentStatus[myValue]}} 

fallirà, perché non ha accesso ai tipi di importazione (Viene eseguito in seguito da Angolare).

per farlo funzionare, il componente dovrà avere un riferimento al tipo enum/oggetto, qualcosa di simile:

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

    myValue : AgentStatus; 
    // ... 
} 

Runnable Demo

Ecco un esempio che spiega tutto quello che ho sottolineato qui:

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

cercare nel file: app/app.component.ts.

3

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

Si hanno states:AgentStatus = AgentStatus. Qui states:AgentStatus è in realtà un valore di tipo AgentStatus dove come = AngentStatus è il intero enum.

Fix

probabilmente vuole:

states:typeof AgentStatus = AgentStatus 

O

states:AgentStatus = AgentStatus.Available 

Più

Questo è simile a si tenta di assegnare foo:SomeClass = SomeClass invece di foo:SomeClass = new SomeClass().

+0

Grazie, ho aggiornato la domanda con i tuoi consigli. Ora ottenendo un errore incredibilmente criptico. Tscript sembra felice però. browser_adapter.ts: 78EXCEPTION: Errore: Uncaught (promessa): TypeError: Impossibile leggere la proprietà 'isSkipSelf' di null – Simon