typescript - Vet ikke hvordan man implementerer en enum ved bruk av et interface i en Angular2-klasse


Går rundt i sirkler her. Veldig ny på Typescript, og det gir store hodepiner med trivielle implementeringer.

Hvordan definerer jeg i AgentStatusService at den skal ha et array med 4 alternativer kalt ['offline','available','busy','away']? AgentStatus er definert (eller er det?) og jeg injiserer det inn i AgentStatusService.

Microsoft Visual Studio Code kaster en feil på linje 21 hvor typen 'typeof AgentStatus' ikke kan tildeles typen 'AgentStatus'... hvorfor?

Oppdatert:

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

Sammenlign med Denne implementeringen tilfredsstiller 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;    
    }
}

Svar #1

Det er ikke åpenbart hva du vil her, men la meg forklare noen ting...

Jeg har laget et blogginnlegg som snakker om dette:
Hvordan bruke TypeScript Enums, spesielt med Angular 2+
Men jeg vil inkludere all informasjonen direkte her:

En enum er bare et objekt. Din enum er skrevet omtrent slik i JavaScript:

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

Fordelen med typing er svært begrenset i enums.

Denne linjen er gyldig:

var value = <AgentStatus>"offline";

Men det er ikke nyttig, fordi

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

Så du bør alltid lagre verdiene dine som tall, som du kan få på følgende måte:

Hvordan konvertere streng til 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"];

Dette gjør den forrige sammenligningen mulig:

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

Nå gjenstår et par spørsmål:

Hvordan får du streng-ekvivalenten?

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

Hvordan får du alle mulige enum-verdier?

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

Forstått

Hvis du skriver dette i malen din:

{{AgentStatus[myValue]}}

Det vil mislykkes, fordi det ikke har tilgang til importerte typer (det blir kjørt senere av Angular).

For å få det til å fungere, må komponenten din ha en referanse til enum-typen/objektet, noe sånt som:

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

    myValue : AgentStatus;
    // ...
}

Kjørbar demo

Her er et eksempel som forklarer alt jeg har pekt på her:

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

Se i filen: app/app.component.ts.

Svar #2

Microsoft Visual Studio Code kaster opp på linje 21 der typen 'typeof AgentStatus' ikke kan tildeles typen 'AgentStatus'... hvorfor

Du har states:AgentStatus=AgentStatus. Her er states:AgentStatus faktisk en verdi av typen AgentStatus, mens = AgentStatus er hele enumen.

Fiks

du vil sannsynligvis ha:

states:typeof AgentStatus = AgentStatus

Eller

states:AgentStatus = AgentStatus.Available

Mer

Dette ligner på at du prøver å tilordne foo:SomeClass=SomeClass i stedet for foo:SomeClass=new SomeClass().

Relaterte artikler