ค้นหาเว็บไซต์

typescript - แนวปฏิบัติที่ดีเกี่ยวกับโมเดลใน Angular คืออะไร?


ฉันต้องการจะแสดงเครื่องซักผ้าในแอป Angular ของฉัน ในการทำเช่นนั้น ฉันได้สร้างโมเดล Machine:

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

และผู้ใช้เครื่องจักร:

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. ฉันจะทำการ duck typing สำหรับโมเดล User ได้อย่างไร? คุณสมบัติ getUsername() ดูเหมือนจะทำให้มันเสีย.

  2. ฉันต้องการเพิ่มตัวจับเวลาลงในเครื่องจักรเพื่อแสดงระยะเวลาของรอบ ฉันสามารถเพิ่มคุณสมบัติ startTimer() และ stopTimer() ให้กับโมเดล Machine ของฉันได้ แต่ก็ต้องการคุณสมบัติเพิ่มเติมอย่างเช่น Observer ที่ไม่เกี่ยวข้องกับข้อมูลของเครื่องจักรและจะทำให้ duck typing ใช้งานไม่ได้เช่นกัน

วิธีที่แนะนำในการจัดการกับสถานการณ์นี้คืออะไร?

แก้ไข

ในที่สุดฉันก็พบแพ็กเกจ class-transformer บน NPM เพื่อที่จะทำมัน

คำตอบ #1

ดูเหมือนว่าคุณต้องการสร้างอินสแตนซ์ของวัตถุโดยใช้สัญลักษณ์วัตถุพร้อมกับทุกฟิลด์และคุณสมมติว่าควรเพิ่มเมธอดเข้าไปยังวัตถุที่สร้างขึ้นในบางวิธี

ทางเลือกที่ใกล้เคียงที่สุดคือการเพิ่มคอนสตรัคเตอร์ให้กับคลาสที่รับอ็อบเจ็กต์ซึ่งประกอบด้วยค่าตั้งต้นสำหรับฟิลด์ต่างๆ:

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',
    ...
})

ฉันยังแนะนำให้หลีกเลี่ยงการใช้คลาสเป็นการใช้งานอินเทอร์เฟสที่นี่ (เช่น class WashingMachine : IMachineOptions) เพื่อที่คุณจะสามารถซ่อนรายละเอียดการใช้งานได้ (ความหมายของฟิลด์ภายในอาจแตกต่างจากตัวเลือก)

อัปเดต: ถ้าคุณต้องการที่จะได้วัตถุเครื่องที่พร้อมใช้งานจากบริการเว็บ API คุณสามารถห่อหุ้มการตอบสนองจากเซิร์ฟเวอร์ใด ๆ ในบริการนั้น:

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