我用的是 ng-select 自定义服务器端搜索,根据用户输入的内容加载数据。目前,只有当一个关键字被实际按下时,它才会工作。我想在每次打开下拉菜单时触发http请求,即使搜索词是空的。
组件.html
<ng-select [items]="filterValues$ | async"
[typeahead]="filterValuesInput$"
[multiple]="true"
(open)="getFilterValues(pref.id)"
[loading]="filterValuesLoading"
bindLabel="name"
[(ngModel)]="filter_values">
</ng-select>
组件.ts
getFilterValues(filterId) {
this.filterValues$ = concat(
of([]), // default items
this.filterValuesInput$.pipe(
distinctUntilChanged(),
tap(() => this.filterValuesLoading = true),
switchMap(term => this.service.getFilterValues(filterName, '' + term).pipe(
map(res => res.filter_values),
catchError(() => of([])), // empty list on error
tap(() => this.filterValuesLoading = false)
))
)
);
}
我想知道switchMap()是如何在输入值被输入后才触发请求的,如何让它在每次调用getFilterValues方法时触发服务的方法?如何让它在每次调用getFilterValues方法时触发服务的方法?
switchMap()只有在输入值被输入后才会触发请求。
我认为 distinctUntilChanged
函数是罪魁祸首。
根据文档 switchMap()
只取消之前的obervables。
看看这个例子,当我注释出 distinctUntilChanged
选择输入输出值,而不考虑之前的状态。
const subject = new rxjs.Subject();
const obs = subject.pipe(
//rxjs.operators.distinctUntilChanged(),
rxjs.operators.switchMap(value =>
rxjs.of("apples", "bananas", "oranges").pipe(
rxjs.operators.filter(pr => pr.includes(value))
)
)
);
const subscription = obs.subscribe(value => {
console.log(value);
});
var selectEl = document.getElementById("select");
selectEl.addEventListener("click", filter);
selectEl.addEventListener("change", filter);
function filter(event) {
subject.next(event.target.value)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.5/rxjs.umd.js"></script>
<select id="select">
<option>a</option>
<option>b</option>
</select>