typescript - Hva er god praksis når det gjelder modeller i Angular?


Jeg vil gjerne vise en vaskemaskin i Angular-appen min. For å gjøre det, laget jeg en Machine-modell:

import { User } from './user.model';

export class Machine {
  id: number;
  type: string;
  pricing: string;
  enableDurationSelection: boolean;
  maxDuration: number;
  costPerCycle: number;
  elapsedTime?: number = 0;
  user?: User;
}

og en maskinbruker:

export class User {
  id: number;
  firstName?: string;
  lastName: string;
  balance: number;

  getUsername(): string {
    let username = '';
    if (this.firstName) {
      username += this.firstName[0] + '. ';
    }
    username += this.lastName.toUpperCase();
    return username;
  }
}
  1. Hvordan kan jeg utføre duck typing for User-modellen? getUsername()-egenskapen ser ut til å ødelegge det.

  2. Jeg vil gjerne legge til en timer på maskinen for å vise varigheten av en syklus. Jeg kunne legge til startTimer() og stopTimer() egenskaper i min Machine-modell, men det trenger også ekstra egenskaper som en Observer som ikke er relatert til maskindataene og som også vil ødelegge duck typing.

Hva er den anbefalte måten å håndtere denne situasjonen på?

Rediger

Endelig fant jeg klasse-transformer-pakken på NPM for å gjøre det.

Svar #1

Det ser ut som du vil opprette objektinstanser ved å bruke objektnotasjon med alle feltene, og du antar at metoder på en eller annen måte bør legges til det opprettede objektet.

Det nærmeste alternativet ville være å legge til en konstruktør i klassen som aksepterer et objekt som inneholder startverdier for feltene:

interface MachineOptions {
    id : number;
    type: string;
    ...
}

export class WashingMachine {
    // field declarations here

    public constructor(options: MachineOptions) {
        // copy options to instance's fields here
    }
}


const machine = new WashingMachine({
    id: 1,
    type: 'm-type1',
    ...
})

Jeg foreslår også å unngå å bruke klassen som grensesnittimplementering her (som class WashingMachine : IMachineOptions) slik at du kan skjule implementasjonsdetaljer (intern feltssemantikk kan avvike fra alternativer).

OPPD: hvis du vil få et ferdiglaget maskinobjekt fra en nett-API-tjeneste, kan du pakke inn svaret fra en server et sted i den tjenesten:

class MachineService {
    getMachine(id: number): Observable<WashingMachine> {
         return this.http
             .get(`/machine/${id}`) // edit the API call as needed
             .pipe(map(options => new WashingMachine(options)); // wrapping part
    }
}

class MachineComponent {
   ...
   ngOnInit() {
       // Example of usage
       this.machineService
           .getMachine(1)
           .subscribe(m => m.startTimer());
   }
}