Как передать значение наблюдаемого субъекту rxjs? - PullRequest
0 голосов
/ 20 сентября 2018

Я хотел бы предоставить rxjs Subject из службы Angular, чтобы иметь возможность передавать значения (через next), вызывая методы службы.Одно из значений, которые я хочу выдать, является результатом вызова Angular HttpClient get.Я просто не могу понять это правильно.Мне интересно, почему в обработчике подписки не вызываются следующие результаты:

-View

export default abstract class TileView implements OnInit {
  constructor (private configService : ConfigService) {}
  ngOnInit () {
    this.configService.fetch(this.type()).subscribe( res => {
      console.log(res)
    }); 
  }
}

-Service

export class ConfigService {
  public subject = new AsyncSubject();

  constructor (private http : HttpClient) {}

  fetch (type) {
    this.http.get(
      api.host + api.base + interpolate(api.config, { type }) + "/"
    ).subscribe( res => {
      this.subject.next(res);
    });

    return this.subject;
  }
}

Есть ли способ вернутьсубъект, а также запустить вызов HTTP с помощью одного вызова метода?Это странно, потому что тема возвращается, подписчик зарегистрирован, вызов http завершается и вызывается this.subject.next(res), но обработчик подписки даже не запускается.

Ответы [ 4 ]

0 голосов
/ 20 сентября 2018

Одной из особенностей AsyncObservable является то, что он ожидает выполнения операции " complete () " перед отправкой информации

Это необязательно, поскольку AsyncSubject расширяет Observable, но япредлагаем вам использовать " return this.subject.asObservable () ", который является частью объекта "Subject".Так как вам нужно использовать его для другого типа предмета, если вы измените тип вашего предмета на BehaviourSubject , например, вам не нужно будет менять свой код;)

0 голосов
/ 20 сентября 2018

Пьер, причина, по которой это происходит, заключается в том, что AsyncSubject испускает последнее значение только тогда, когда наблюдаемое завершает (определяется Subject.prototype.complete()).

В вашем случае вы, вероятно, захотите использовать BehaviorSubject, который выдает последнее значение в потоке, для подписчиков независимо от завершения:

AsyncSubject выдает последнее значение (и толькопоследнее значение), испускаемое источником Observable, и только после этого источник Observable завершает работу.(Если исходная наблюдаемая не генерирует никаких значений, AsyncSubject также завершает работу без каких-либо значений.)

Предметная документация

Обновление:

Если вы не хотите использовать BehaviorSubject из-за распространения начального значения, используйте ReplaySubject (1).

0 голосов
/ 20 сентября 2018

завершите наблюдаемое, и оно будет работать

fetch (type) {
    this.http.get(
      api.host + api.base + interpolate(api.config, { type }) + "/"
    ).subscribe( res => {
      this.subject.next(res);
      this.subject.complete();
    });

    return this.subject;
  }

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

public behaviourSub = new BehaviorSubject(null);

this.configService.fetch(this.type()).subscribe( res => {
    if (res !== null) {
      // actual value emitted
    }
});
0 голосов
/ 20 сентября 2018

Подпишитесь на "тему" по вашему мнению, чтобы не получить.И не нужно также возвращать тему из вашего сервиса.

просмотр:

export default abstract class TileView implements OnInit {
  constructor (private configService : ConfigService) {}
  ngOnInit () {
    this.configService.subjectChanged(this.type()).subscribe( res => {
      console.log(res)
    }); 
  }
}

Сервис: класс экспорта ConfigService {

  public subjectChanged = new Subject();

  constructor (private http : HttpClient) {}

  fetch (type) {
    this.http.get(
      api.host + api.base + interpolate(api.config, { type }) + "/"
    ).subscribe( res => {
      this.subjectChanged.next(res);
    });
  }
}
...