Rx js Наблюдается, не передавая последние данные всем подписчикам - PullRequest
0 голосов
/ 27 февраля 2020

Я объявил субъект в обслуживании и попытался получить sh ответ, полученный при выполнении вызова GET для внутреннего интерфейса с использованием "subject.next ()" .. также назначил наблюдаемое для субъекта с помощью "subject.asObservable () "и подписался на наблюдаемое в двух разных компонентах (родительский и маршрутизатор, дочерний объект). Проблема заключается в том, что наблюдаемое излучает новое значение только для одного подписчика, а не для двух подписчиков.

услуга

subject = new Subject<any>();
  observable = this.subject.asObservable();


 public getDetails(id) {
    return this.http.get(this.url.concat(id))
      .pipe(map(data => this.extractDetails(data),
            catchError(err => this.handleError(err)));
  }
 public extractDetails(data){
    this.subject.next(data);
    return data;
  }

Родительский компонент

ngOnInIt(){
 this.hitUrl();

}
getDetails(){
    this.service.observable.subscribe(
      (data: any) => {
        console.log(data);
      },
      err => {
        console.error(err);
      }
    )
  }

  hitUrl(id: string) {
    this.service.getDetails(id).subscribe(
      (data: any) => 
        if(!!data){
            console.log(data);
            this.getDetails();
          }
      },
      err => {
        console.log(err);
      }
    );
  }

дочерний компонент маршрутизатора-розетки

ngOnInIt(){
 this.hitUrl();

}
getDetails(){
    this.service.observable.subscribe(
      (data: any) => {
        console.log(data);
      },
      err => {
        console.error(err);
      }
    )
  }

  hitUrl(id: string) {
    this.service.getDetails(id).subscribe(
      (data: any) => 
        if(!!data){
            console.log(data);
            this.getDetails();
          }
      },
      err => {
        console.log(err);
      }
    );
  }

В компонентах hitUrl () также срабатывает при выполнении вызова к действию, затем Мне нужно, чтобы наблюдаемые должны выдавать последние данные обоим подписчикам (если призыв к действию выполняется от родительского или дочернего маршрутизатора).

1 Ответ

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

Вы путаете понятия. В вашей функции service.getDetails вы возвращаете новую наблюдаемую информацию каждый раз, когда вызывается функция. Итак, ваш observable атрибут не используется. Вы должны экспортировать только атрибут observable и сохранять getDetails закрытым, вызывая эту функцию только для извлечения данных.

Как создать кэш службы

BehaviorSubject

Вы можете использовать BehaviorSubject, вариант Subject, который требует начального значения и выдает свое текущее значение всякий раз, когда он подписан.

private subject = new BehaviorSubject<any>();
private observable = this.subject.asObservable();

  public getDetails(id) {
    if (!this.observable) {
      this.loadData();
    }
    return this.observable;
  }

  private loadData() {
    this.http.get(this.url.concat(id))
    .subscribe(data => {
      this.subject.next(data);
    })
    this.observable = this.subject.asObservable();
  }

shareReplay

Лучший способ - использовать rx js shareReplay . Этот оператор возвращает Observable, который разделяет одну подписку на базовый источник. Другими словами, это делает нашу наблюдаемую горячую.

const CACHE_SIZE = 1;
class Service { 

  private _data$: Observable<YourType>;

  get data(): Observable<YourType> {
    if (!this._data$) {
      this._data$ = anyHttpCall()
        .pipe(shareReplay({ refCount: true, bufferSize: CACHE_SIZE })
      );
    }
    return this._data$;
  }
}

bufferSize определяет максимальное количество элементов буфера воспроизведения, то есть количество элементов, которые кэшируются и воспроизводятся для каждого подписчика. .

Этот пост объясняет это очень хорошо: https://blog.thoughtram.io/angular/2018/03/05/advanced-caching-with-rxjs.html

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