【发布时间】:2020-08-03 18:38:13
【问题描述】:
我正在开发一个 Angular 库。
目前,当我想从我的 API 中检索数据时,我会使用我的服务:
@Injectable()
export class ProductService {
public getProduct(id: number): Observable<Product> {
// return response of http request
}
}
这是一个基本方法,只返回一个产品是一个接口 现在,我改进了我的方法以返回一个 Product 类,它可以包含方法、其他参数等。
@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 收集的产品信息,或者添加检索一个或多个产品的静态函数:
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 时经常使用的一种模式。可以在这样的组件中使用 Products:
ngOnInit() {
this.$product = Product.get(this.id);
this.$variants = this.$product.pipe(switchMap(product => product.variants))
this.$products = Product.list(5, 0)
}
在所有这些代码行之后,这是我的问题:
Product 类在 Angular 范围之外,它既不是服务也不是模块。 所以我无法使用依赖注入来获取 ProductService(或任何像 HttpClient 这样的服务)。 我怎样才能做到这一点?每次实例化一个新产品时我都必须提供服务吗?我可以使用单例服务并在我的 Product 实例中检索它吗?
我发现了这个问题:Getting instance of service without constructor injection 有一个问题解释了如何在应用程序的任何地方导入服务。有更好的解决方案吗?或者也许我的模式是带有角度的反模式。
【问题讨论】:
-
恕我直言,这个想法是使用该服务,所以是的,我将其称为反模式。可以将服务注入普通类,但我认为这不是一种非常干净的方式。
this.$product = Product.get(this.id);和this.$product = this.productService.get(this.id);到底有什么区别?! -
这种模式的作用是只使用一个类作为 Entity 和 EntityManager 并且服务将只是一个
client用于简单地返回 http 请求响应的 api。跨度>
标签: angular typescript