簡體   English   中英

多個組件同時訪問相同的數據

[英]multiple components accessing same data at same time

在我的角度應用程序中,我有一個由 3 個不同組件組成的儀表板

1)左菜單組件

2) 右鍵菜單組件

3)讓我們說中心組件

這三個都需要訪問相同的 api 響應。 早些時候,我以這樣一種方式編碼,當加載這些組件中的每一個時,設置 api 被命中並獲取數據。所以對於相同的數據,總共有 3 次 api 調用。 我想改變這個

我想點擊 api 一次,並且加載時所有三個組件的數據都必須可用。

我嘗試了事件發射器,但 api 並沒有被擊中。

下面是api調用。

getUserSettings(): Observable<any> {
    var userSettUrl = this.baseUrl + this.ngAuth.getApiUrl('settings');
    let httpHeader = {
      headers: new HttpHeaders({
        'Content-Type': 'application/x-www-form-urlencoded'
      })
    };
    return this.http.get(userSettUrl, httpHeader)
      .map((res: any) => {
        var obj = res;
        return this.userSettings = obj.settings;
      });
  }

在每個組件 ngOnInit() 中都添加了訂閱。 我想優化它

請指導

謝謝施魯蒂

優化的解決方案是創建一個緩存響應,因此您點擊一次並從中獲取其他組件的副本。如果 api 響應已經存在。我將分享我在 angular 5 中使用的示例。

  //In service
    cacheCommonSuccess$: Observable<any>;

     public getSuccessCommonMsg() {
        if (!this.cacheCommonSuccess$) {
          this.cacheCommonSuccess$ = this.requestSuccessCommonMsg();
        }
        return this.cacheCommonSuccess$;
      }



   private requestSuccessCommonMsg() {
    const url = this.API_BASE_URL + '/api/successmessages.json';
    return this.http.get(url).pipe(
      map(response => response[0]), shareReplay()
    );
  }


//In all three components 



 // To get stored success msgs from shared component
  getSuccessCommonMsgs() {
    this._SharedServiceService.getSuccessCommonMsg().subscribe(res => {
      this.apiResponseGSuccess = res;      
    });
  }

或者,如果可能,您可以在父組件中調用此 api 並將其傳遞給所有子組件(如在 react js 中)。

  1. 制作一個父組件,我們稱之為具有左菜單組件的儀表板 右側菜單組件中央組件作為子組件。

  2. 請對儀表板組件下getUserSettings的呼叫(在ngOnInit())。

  3. 使用@Input @Output裝飾器將 api 響應數據傳遞給子組件,或者僅使用Behavior Subject(Service)的概念在組件之間共享數據。

注意 如果您使用Behavior Subject(Service) ,則無需建立父子關系。

最簡單的方法是使用shareReplay(1)這將自動將您的響應放入ReplaySubject下的ReplaySubject ,並且所有訂閱組件將從重播主題接收值,而不是執行 API 調用。 因此,您的服務可以執行以下操作:

getUserSettings(): Observable<UserSettings> {
    var userSettUrl = this.baseUrl + this.ngAuth.getApiUrl('settings');
    let httpHeader = {
      headers: new HttpHeaders({
        'Content-Type': 'application/x-www-form-urlencoded'
      })
    };
    return this.http.get(userSettUrl, httpHeader).pipe(
      map((res: any) => obj.settings),
      shareReplay(1)
    );
  }

然后在您的組件中,您可以簡單地訂閱它並通過直接訂閱或使用async管道來獲取結果。 如果您使用我推薦的OnPush策略,請確保在直接訂閱時取消訂閱並處理更改檢測。

當然,其他替代方案也可以奏效。 例如提到了 ngrx,它可以是共享應用程序范圍數據的好方法,但需要更多的努力來整合。

暫無
暫無

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

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