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().
