我有一个搜索栏,可以根据ID搜索事件。随着在搜索栏中键入更多数字,它会不断更新以根据键入的部分ID搜索事件。因此,当我停止键入内容时,最新的结果将根据先前的请求进行更新。
示例。我输入12345进行搜索。
显示的结果为12345
然后通过1234的结果进行更新。
然后它被123的结果更新。
更新:
'''
export class SearchComponent implements OnInit {
events: Events[]
triggered = false
constructor(private eventService: EventService) {
}
ngOnInit() {
this.events = <Events[]>[]
}
searchForEvents(searchTerm) {
this.eventService.getEventsByPartialId(searchTerm)
.subscribe(data => this.events = data)
this.triggered = true
}
}
'''
答案 0 :(得分:2)
如果您使用用于这些特定方案的标准RxJS运算符,我想您应该找到想要的东西,
map
-将keyup
事件转换为可用于搜索的文本。debounceTime
-等待x毫秒后再执行操作。因此,如果用户在这x毫秒内更改了任何内容,则不会考虑。distinctUntilChanged
-检查该值是否在x毫秒内实际上已更改。tap
-在实际进行API调用之前设置加载状态。switchMap
-将Observable的上下文切换为http.get
调用的结果。catchError
-为了处理API带来的错误,以防万一。尝试一下:
import { Component, Injectable, ViewChild, ElementRef } from '@angular/core';
import { Observable, fromEvent, of } from 'rxjs';
import { map, distinctUntilChanged, debounceTime, tap, switchMap, catchError } from 'rxjs/operators';
import { SearchService } from './search.service';
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"],
})
export class AppComponent {
model: Observable<any>;
searching = false;
searchFailed = false;
searchField$: Observable<any>;
@ViewChild('input', { static: true }) input: ElementRef;
constructor(private _service: SearchService) { }
ngAfterViewInit() {
this.searchField$ = fromEvent(this.input.nativeElement, `keyup`);
this.model = this.searchField$.pipe(
map(event => event.target.value),
debounceTime(300),
distinctUntilChanged(),
tap(() => this.searching = true),
switchMap(term =>
this._service.search(term).pipe(
tap(() => this.searchFailed = false),
catchError(() => {
this.searchFailed = true;
return of([]);
}))
),
tap(() => this.searching = false)
);
}
}
这是您推荐的Working Sample StackBlitz。