簡體   English   中英

我可以為 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)});
  }
}

客戶端應該能夠打開多個具有不同id edit-order.component 在我的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$ 我將如何實現這一目標? 或者這是不可能的? 如果不可能,我還能做些什么來實現我的目標?

創建不同的服務實例是一個非常糟糕的主意。 該服務的目的是 singleton,這就是它的設計方式。 您可以使用它的一個好方法是為每個可觀察的訂單保存一個鍵值 object。 從父組件將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;
    })
  }

}

好奇,為什么不是你的 function 是

getOrderById(id: string){
    return this.http.get('url', {params: {id}})
  }

你訂閱了getOrderById嗎?

如果你願意,你可以通過管道(catchError)

更新您也可以在服務中使用“緩存”而不使用主題數組,僅使用 object 數組

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM