switchMap
работает путем отмены предыдущего запроса при предоставлении нового значения.В вашем коде вы каждый раз создаете новую наблюдаемую информацию, поэтому отменить нечего.
Вам необходимо иметь долговременную наблюдаемую над параметрами фильтра.Затем вы можете подписаться на результаты этого наблюдения с помощью switchMap
и получить данные из сервиса.Примерно так:
Компонент:
@Component({})
export class ExampleComponent implements OnDestroy {
private readonly _paramsSubject: BehaviorSubject<any>(null); // Here are the filters
readonly data$ = this._paramsSubject
.pipe(switchMap(params => this.dataService.getData(params))); // subscribe to the filter changes and switchMap to data service
setFilters(filters: any) {
// push new filters into the subject
this._paramsSubject.next(filters);
}
ngOnDestroy() {
// need to close the subject
this._paramsSubject.complete();
}
}
Шаблон:
<!-- Click on this button would update filters and trigger data loading -->
<button type="button" (click)="setFilters('new_filter')">Set filters</button>
<div *ngIf="data$ | async; let data">
<!-- Data is available here -->
{{data | json}}
</div>
Примечание: BehaviorSubject
используется здесь, чтобы иметь начальное значение null
, когдаВызов данных службы.Если вам не нужно вызывать службу данных, пока пользователь не выберет фильтры в первую очередь, тогда вы можете заменить BehaviourSubject
на обычный
Кроме того, канал async
не является строго необходимым, вы можете просто подписаться насубъект params в вашем методе ngOnInit()
, но в таких случаях предпочтительнее использовать трубу async
.
В качестве бонуса теперь вы можете расширить свою трубу.Некоторые полезные операторы для вашего случая:
debounceTime
- отменить быстрые изменения фильтров ( документация ); distinctUntilChanged
- делать запросы только тогда, когда фильтрыбыли действительно изменены ( документация ).