我可以为 Angular 中的每个加载组件创建一个服务实例吗?
Can I create an instance of a service for every loaded component in Angular?
我有一个名为 edit-order.component
的组件,其中包含以下 ts 文件
export class EditOrderComponent implements OnInit {
constructor(private editOrderSrv: EditOrderService, private route: ActivatedRoute) { }
ngOnInit(): void {
this.editOrderSrv.getOrderById(this.route.snapshot.params.id);
}
}
在我的 edit-order-service.service.ts
中有以下代码
export class EditOrderService {
order$: BehaviorSubject<any> = new BehaviorSubject(null);
constructor(private http: HttpClient) { }
getOrderById(id: string){
this.http.get('url', {params: {id}}).subscribe(order => {
this.order$.next(order);
}, error => {console.error(error)});
}
}
客户端应该可以打开多个 edit-order.component
不同 id
。在我的 child.component
我想订阅 order$
这样的
export class ChildComponent implements OnInit {
order: any;
constructor(private editOrderSrv: EditOrderService) { }
ngOnInit(): void {
this.editOrderSrv.order$.subscribe(order => {
if(order) this.order = order;
})
}
}
但因此我必须为每个 edit-order.component
拥有自己的服务实例,以免覆盖 order$
。我将如何实现这一目标?或者这是不可能的?如果不可能,我还能做些什么来实现我的目标?
创建服务的不同实例是一个非常糟糕的主意。该服务的目的是成为单身人士,这就是它的设计方式。
使用它的一个好方法是为每个可观察的订单保存一个键值对象。从父组件将 this.route.snapshot.params.id
作为输入传递给子组件。
(代码未经测试)
服务:
export class EditOrderService {
public orders$: { [orderid: string]: BehaviorSubject<any> } = {};
constructor(private http: HttpClient) { }
getOrderById(id: string): void {
this.http.get('url', { params: { id } }).subscribe(order => {
if (!this.orders$[id]) {
this.orders$[id] = new BehaviorSubject<any>(null);
}
this.orders$[id].next(order);
}, error => { console.error(error); });
}
}
子组件:
export class ChildComponent implements OnInit {
order: any;
@Input() orderId: any;
constructor(private editOrderSrv: EditOrderService) { }
ngOnInit(): void {
this.editOrderSrv.orders$[orderId].subscribe(order => {
if(order) this.order = order;
})
}
}
好奇,为什么你的功能不是
getOrderById(id: string){
return this.http.get('url', {params: {id}})
}
你订阅了getOrderById
?
如果你愿意,你可以管道(catchError)
Update 你也可以在服务中使用“缓存”而不使用 Subject 数组,只使用对象数组
orders:any={} //create an empty object where we store the result
getOrderById(id: string){
if (this.orders[id])
return of(this.orders[id]
return this.http.get('url', {params: {id}}).pipe(
tap(res=>{
this.orders[id]=res;
})
)
}
我有一个名为 edit-order.component
的组件,其中包含以下 ts 文件
export class EditOrderComponent implements OnInit {
constructor(private editOrderSrv: EditOrderService, private route: ActivatedRoute) { }
ngOnInit(): void {
this.editOrderSrv.getOrderById(this.route.snapshot.params.id);
}
}
在我的 edit-order-service.service.ts
中有以下代码
export class EditOrderService {
order$: BehaviorSubject<any> = new BehaviorSubject(null);
constructor(private http: HttpClient) { }
getOrderById(id: string){
this.http.get('url', {params: {id}}).subscribe(order => {
this.order$.next(order);
}, error => {console.error(error)});
}
}
客户端应该可以打开多个 edit-order.component
不同 id
。在我的 child.component
我想订阅 order$
这样的
export class ChildComponent implements OnInit {
order: any;
constructor(private editOrderSrv: EditOrderService) { }
ngOnInit(): void {
this.editOrderSrv.order$.subscribe(order => {
if(order) this.order = order;
})
}
}
但因此我必须为每个 edit-order.component
拥有自己的服务实例,以免覆盖 order$
。我将如何实现这一目标?或者这是不可能的?如果不可能,我还能做些什么来实现我的目标?
创建服务的不同实例是一个非常糟糕的主意。该服务的目的是成为单身人士,这就是它的设计方式。
使用它的一个好方法是为每个可观察的订单保存一个键值对象。从父组件将 this.route.snapshot.params.id
作为输入传递给子组件。
(代码未经测试)
服务:
export class EditOrderService {
public orders$: { [orderid: string]: BehaviorSubject<any> } = {};
constructor(private http: HttpClient) { }
getOrderById(id: string): void {
this.http.get('url', { params: { id } }).subscribe(order => {
if (!this.orders$[id]) {
this.orders$[id] = new BehaviorSubject<any>(null);
}
this.orders$[id].next(order);
}, error => { console.error(error); });
}
}
子组件:
export class ChildComponent implements OnInit {
order: any;
@Input() orderId: any;
constructor(private editOrderSrv: EditOrderService) { }
ngOnInit(): void {
this.editOrderSrv.orders$[orderId].subscribe(order => {
if(order) this.order = order;
})
}
}
好奇,为什么你的功能不是
getOrderById(id: string){
return this.http.get('url', {params: {id}})
}
你订阅了getOrderById
?
如果你愿意,你可以管道(catchError)
Update 你也可以在服务中使用“缓存”而不使用 Subject 数组,只使用对象数组
orders:any={} //create an empty object where we store the result
getOrderById(id: string){
if (this.orders[id])
return of(this.orders[id]
return this.http.get('url', {params: {id}}).pipe(
tap(res=>{
this.orders[id]=res;
})
)
}