Не удается обнаружить первое наблюдаемое изменение / представление не обновляется - PullRequest
0 голосов
/ 24 мая 2018

У меня есть небольшая проблема с подпиской моего Observable

У меня есть один объединенный Observable:

private selectedEntryId$ = new Subject<number>();
private entries$ = new Subject<MappingEntry[]>();

private selectedEntry$ = Observable.combineLatest(
    this.entries$,
    this.selectedEntryId$,
    (entries: MappingEntry[], id: number) => {
        return entries.find((entry: MappingEntry) => {
            return entry.id === id;
        });
    });

Я пытаюсь делать вызов API каждый раз, когда мой selectedEntry$ имеет следующее значениеи подписать результат следующим образом:

constructor(private checkService: CheckService) {
    this.subscribeLengthCalculator();
}

subscribeLengthCalculator() {
    this.subscriptions.add(
        this.selectedEntry$
            .switchMap((entry) => {
                return entry ? this.checkService.calculateLinesLength([entry.value]) : Observable.empty();
            }).subscribe(([calculation: CalculationObject]) => {
                    console.log(calculation);
                    this.calculation = calculation;
             })
    );
}

В первый раз, когда selectedEntry$ имеет следующее значение, console.log выдает на консоль правильный результат API, но в моем html calculation имеет нулевое значение.Когда selectedEntry$ имеет второе следующее значение, console.log также выдает на консоль правильный результат API, но в html показывает mi предыдущее значение.Кто-нибудь может объяснить мне это поведение и сказать, что я должен сделать, чтобы отобразить текущие данные в HTML?Это очень странное поведение.

1 Ответ

0 голосов
/ 25 мая 2018

Цитирование learnrxjs"Однако будьте осторожны, вы, возможно, захотите избегать switchMap в сценариях, где нужно выполнить каждый запрос".

"Основное различие между switchMap и другими«Сглаживающие операторы - это эффект отмены», поэтому, когда selectedEntry$ имеет второе следующее значение, оно показывает ваше предыдущее значение.Наблюдаемый источник (this.selectedEntry$) a; готово, подписка просто активна для Observable, поступающего с этой строки:

return entry ? this.checkService.calculateLinesLength([entry.value]) : Observable.empty()

Итак, с учетом сказанного я рекомендую попробовать concatMapвместо switchMap:

subscribeLengthCalculator() {
    this.subscriptions.add(
        this.selectedEntry$
            .concatMap((entry) => {
                return entry ? this.checkService.calculateLinesLength([entry.value]) : Observable.empty();
            }).subscribe(([calculation: CalculationObject]) => {
                    console.log(calculation);
                    this.calculation = calculation;
             })
    );
}

но на самом деле я люблю операторов конвейера, поэтому ответ будет:

import { concatMap } from 'rxjs/observable/concatMap';

subscribeLengthCalculator() {
        this.subscriptions.add(
            this.selectedEntry$
                .pipe(
                    concatMap((entry) => {
                        return entry ? this.checkService.calculateLinesLength([entry.value]) : Observable.empty();
                    })
                ).subscribe(([calculation: CalculationObject]) => {
                    console.log(calculation);
                    this.calculation = calculation;
                })
        );
    }
...