несколько компонентов обращаются к одним и тем же данным одновременно - PullRequest
1 голос
/ 12 февраля 2020

В моем приложении angular есть панель управления, которая состоит из 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 () подписка добавляется. Я хочу оптимизировать его

Пожалуйста, руководство

Спасибо Шрути

Ответы [ 3 ]

0 голосов
/ 12 февраля 2020
  1. Создать родительский компонент, назовем его Панель инструментов , имеющая Левый компонент меню . правый компонент меню и центральный компонент в качестве дочернего компонента.

  2. Выполнение вызова getUserSettings в компоненте панели мониторинга (включено ngOnInit ()).

  3. Передать данные ответов API в дочерний компонент с помощью декоратора @ Input @ Output или просто использовать концепцию Поведение субъекта (службы) для обмена данными между компонентами.

Примечание . Если вы используете Behavior Subject (Service) , вам не нужно иметь отношения родитель-ребенок.

0 голосов
/ 12 февраля 2020

Самый простой способ сделать это - использовать shareReplay(1), это автоматически поместит ваш ответ в 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 pipe. При прямой подписке обязательно отмените подписку и выполните обнаружение изменений, если вы используете стратегию OnPush, которую я рекомендую.

Конечно, другие альтернативы также могут работать. Например, было упомянуто ngrx, это может быть хорошим подходом для обмена данными в масштабе приложения, но для его объединения требуется гораздо больше усилий.

0 голосов
/ 12 февраля 2020

Оптимизированным решением будет создание cachedResponse, таким образом, вы нажимаете один раз и получаете копию от него для других компонентов. Если ответ 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 в родительском компоненте и передать его всем дочерним компонентам, если это возможно (как в реагировании js).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...