Я работаю над библиотекой Angular.
В настоящее время, когда я хочу получить данные из моего API, я использую свой сервис:
@Injectable()
export class ProductService {
public getProduct(id: number): Observable<Product> {
// return response of http request
}
}
Это базовый c метод, который возвращает только Product, который является интерфейсом Теперь я улучшаю свой метод, возвращая класс продукта , который может содержать методы, другие параметры и т. д. c.
@Injectable()
export class ProductService {
public getProduct(id: number): Observable<Product> {
return this.http.get(`http://myapi/products/${id}`).pipe(
map(response => response.data),
map(productData => {
const product = new Product()
product.unserialize(productData)
return product;
})
)
}
}
Теперь Product - это экземпляр класса Product , и я могу реализовать в нем методы следующим образом:
export class Product extends Unserializable {
...
get variantsCount(): number {
return this.variants.length
}
...
}
На этом этапе все довольно чисто и работает хорошо. Но скажем, я хочу получить информацию о продукте, которую необходимо собрать из API, или добавить stati c функции, извлекающие один или несколько продуктов:
export class Product extends Unserializable {
...
public get $variants (): Observable<ProductVariants> {
return this.productService.getVariants(this);
}
public static get(id: number): Observable<this> {
return this.productService.getProduct(id).pipe(
map(productData => {
const product = new Product()
product.unserialize(productData)
return product;
})
)
}
public static list(limit: number, skip = 0): Observable<this[]> {
return this.productService.getProducts(limit, skip).pipe(
map(productsData => {
// Unserialize every products in the array
...
})
)
}
...
}
Это шаблон, который я часто использую при работе с VueJS. Можно было бы работать с продуктами в таком компоненте:
ngOnInit() {
this.$product = Product.get(this.id);
this.$variants = this.$product.pipe(switchMap(product => product.variants))
this.$products = Product.list(5, 0)
}
После всех этих строк кода, вот мой вопрос:
Класс Product находится за пределами Angular scope, это ни сервис, ни модуль. Поэтому я не могу использовать внедрение зависимостей для получения ProductService (или любой другой службы, например HttpClient). Как я могу этого добиться? Должен ли я предоставлять услугу каждый раз, когда я создаю новый продукт? Могу ли я использовать одноэлементную службу и получить ее в своем экземпляре продукта?
Я нашел этот вопрос: Получение экземпляра службы без внедрения конструктора с вопросом, объясняющим, как импортировать сервис повсюду в приложении. Есть ли лучшее решение ? Или, может быть, мой шаблон - это анти-шаблон с angular.