Angular: создание объекта класса и предоставление услуг - PullRequest
0 голосов
/ 04 мая 2020

Я хочу создать объект User как класс, но он нужен или должен иметь доступ к моим службам. Я не уверен, как это сделать, особенно потому, что я использую constructor() для инициализации своих зависимостей.

Так вот мой User

import { ElementRef, Injectable } from '@angular/core';
import { DbService } from '../service/db.service';
import { ImageService } from '../service/skin.service';

export class User {
    name: string;
    img: ElementRef<HTMLCanvasElement>;

    constructor(
        name: string,
        img?: ElementRef<HTMLCanvasElement> | string[]) {

        this.name = name;

        if (img) {
            if (img instanceof ElementRef) {
                this.img = img;
            } else {
                this.img.nativeElement = this.ImageService.render(img);
            }
        } else {
            DbService.getSkin(name).subscribe(res => this.img.nativeElement.this.service.render(res));
        }
    }
}

Я не Я считаю, что лучший вариант - сделать нужные мне функции public static.

Так как же добавить Db и ImageService?

Ответы [ 3 ]

0 голосов
/ 04 мая 2020

Вы можете создать заводскую службу, в которую вы можете добавить нужные вам службы. Он может иметь метод build, который получает параметры, которые вы должны передать для создания объекта User, а также сервисы, через которые вы хотите пройти:

@Injectable({providedIn: 'root')
export class UserFactory {
  constructor(private _yourService: YourService) {}

  build(name: string, img?: ElementRef<HTMLCanvasElement> | string[]) {
    return new User(name, img, this._yourService);
  }
}

Затем вы можете использовать его следующим образом:

@Component({...})
export class YourComponent {
  ...

  constructor(private _uFactory: UserFactory) {}

  ...

    const user = this._uFactory.buid(name, img);

  ...
}
0 голосов
/ 04 мая 2020

Я бы предложил подумать о SOLID и разделить обязанности.

User - это объект со свойствами name и img. Он не должен знать о DBService.

. Вы можете создать фабрику для создания User экземпляров. И фабрика узнает о DBService. Фабрика может работать двумя способами:

  • синхронно создавать и возвращать экземпляр User, а затем асинхронно заполнять свойство img, если DbService.getSkin будет вызываться
  • создавать и возвращать User экземпляр асинхронно через наблюдаемый - всегда.

Я думаю, что случай 2 лучше, потому что он имеет более предсказуемое поведение и не имеет неожиданного обновления свойства img.

Код будет например:

case1 - вернуть User экземпляр

interface User {
  name: string;
  img: ElementRef<HTMLCanvasElement> | string[];
}

@Injectable({providedIn: 'root')
export class UserFactory {
  constructor(private dbService: DBService) {}

  create(
    name: string,
    img?: ElementRef<HTMLCanvasElement> | string[],
  ): User {
    const user: User = {
      name,
      img,
    }

    if (!img) {
      this.dbService.getSkin(name).pipe(
        tap(someResponse => {
          /* 
            SET IMG HERE
            user.img = someResponse
          */
        }),
      ).subscribe();
    }

    return user;
  }
}

case 2 - вернуть наблюдаемый

interface User {
  name: string;
  img: ElementRef<HTMLCanvasElement> | string[];
}

@Injectable({providedIn: 'root')
export class UserFactory {
  constructor(private dbService: DBService) {}

  create(
    name: string,
    img?: ElementRef<HTMLCanvasElement> | string[],
  ): Observable<User> {
    const user: User = {
      name,
      img,
    }

    let user$: Observable<User> = of(user);

    if (!img) {
      user$ = this.dbService.getSkin(name).pipe(
        map(someResponse => {
          /* 
            SET IMG HERE
            user.img = someResponse
          */
          return user;
        }),
      )
    }

    return user$;
  }
}

Фабрика отвечает за работу с API в обоих случаях , Это решение имеет более четкую структуру и более тестируемо.

0 голосов
/ 04 мая 2020

В конструкторе вы можете инициализировать сервис, передав в качестве аргумента

constructor(name: string,
        img?: ElementRef<HTMLCanvasElement> | string[],private imageService:ImageService ){

    }

Затем вы можете получить доступ к сервису как

this.imageService.getMethod()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...