Сравните самые последние значения из нескольких BehaviorSubjects

Скажи, что у меня есть это:

  isMatchedCountLessThanTotalCountMessage(){
       // I want to implement this
       // "returns" a string asynchronously
  }

  getMatchedEventsCount() {
    return this.dcs.matchCount.asObservable();
  }

  getTotalEventsCount() {
    return this.dcs.totalCount.asObservable();
  }

matchedCount и totalCount выглядят так:

  public matchCount = new BehaviorSubject<number>(0);
  public totalCount = new BehaviorSubject<number>(0);

эти Observables запускают целые числа при изменении значений. Каждый раз, когда значение вызывается одним из них, я хочу сравнить два самых последних значения из обоих, как мне это сделать?

Что я хочу сделать, это вернуть логическое значение из метода

так что я могу отобразить в HTML:

 <div>{{(isMatchedCountLessThanTotalCountMessage() | async)}}</div>

Я думаю, что Observable.zip может добиться цели:

isMatchedCountLessThanTotalCountMessage(){
    return Observable.zip(
      this.getMatchedEventsCount(),
      this.getTotalEventsCount()
    )
    .subscribe(function(v){
      const intA = v[0];
      const intB = v[1];

        if(intA > intB)
         // but I don't know how to send a message the HTML from here
    });
  }

2 ответа

Решение

Вы можете легко использовать .map() Функция для преобразования данных, которые вы хотите:

isMatchedCountLessThanTotalCountMessage() {
    return Observable.combineLatest(
        this.getMatchedEventsCount(),
        this.getTotalEventsCount(),
    )
        .map(([intA, intB]) => {
            return intA > intB ? '(results ARE filtered)' : '(results are not filtered)'
        })
}

Это работает, хотя мы могли бы использовать что-то кроме Observable.zip.

 isMatchedCountLessThanTotalCount() {
    return Observable.create(obs => {
      return Observable.zip(
        this.getMatchedEventsCount(),
        this.getTotalEventsCount()
      )
      .subscribe(v => {
        if ((v[1] - v[0]) > 0) {
          obs.next('(results ARE filtered)')
        }
        else {
          obs.next('(results are not filtered)');
        }
      });
    });
  }

и на самом деле существует более простой способ сделать это с помощью так называемой "проекционной функции":

  isMatchedCountLessThanTotalCount() {
    return Observable.combineLatest(
      this.getMatchedEventsCount(),
      this.getTotalEventsCount(),
      function (one, two) {
        if ((two - one) > 0) {
          return '(results ARE filtered)'
        }
        return '(results are not filtered)';
      }
    )
  }

Observable.combineLatest() похож на Observable.zip() но сработает первое новое значение, оно не будет ждать появления новых значений из всех наблюдаемых.

Другие вопросы по тегам