我目前正在做的是将输入双向绑定设置为appRequestParams.appName
,并且在每个keyup事件中,将调用fetchApps()
方法。
我试图去除输入,以便它不会立即触发每个键盘上的后端http请求。
我已经了解了如何去做这件事,以及我在这里发表的事情。
HTML
<input #searchBox id="search" mdInput placeholder="Search by list of apps" (keyup)="search(searchBox.value)" />
打字稿
private searchTerms = new Subject<string>();
search(value: string): void {
this.searchTerms.next(value);
}
fetchApps() {
this.appService.query({
appName: this.appRequestParams.appName ? this.appRequestParams.appName : null,
}).subscribe(
(res: ResponseWrapper) => this.onSuccess(res.json, res.headers),
(res: ResponseWrapper) => this.onError(res.json)
);
}
ngOnInit() {
this.searchTerms
.debounceTime(300)
.distinctUntilChanged()
.switchMap((value: string) => {
this.appRequestParams.appName = value;
this.fetchApps();
});
}
.switchMap()
:
Argument of type '(value: string) => void' is not assignable to parameter of type '(value: string, index: number) => ObservableInput<{}>'.
Type 'void' is not assignable to type 'ObservableInput<{}>'.
答案 0 :(得分:4)
你的代码的debounce相关部分没问题。问题是你不能在没有返回另一个observable的情况下调用switchMap。
SwitchMap基本上将Observable的最后一个发射值转换为另一个Observable,从而提供了即时自动取消http请求的能力。
尝试以下方法:
private searchTerms = new Subject<string>();
search(value: string): void {
this.searchTerms.next(value);
}
fetchApps() {
this.appService.query({
appName: this.appRequestParams.appName ? this.appRequestParams.appName : null,
});
}
ngOnInit() {
this.searchTerms
.debounceTime(300)
.distinctUntilChanged()
.switchMap((value: string) => {
this.appRequestParams.appName = value;
return this.fetchApps();
}).subscribe(
(res: ResponseWrapper) => this.onSuccess(res.json, res.headers),
(res: ResponseWrapper) => this.onError(res.json)
);
}
典型示例与ActivatedRoute中的路径参数相关联。请考虑以下事项:
@Injectable()
export class FooService{
..
getFooById(id:string): Observable<FooInterface>{
return this.http.get('endpoint/${id}')
.map(res=>res.json())
.catch(_throw(error));
}
}
现在我们导航到root / foo / 10980312,其中最后一部分在路由中定义为:id
@Component({...})
class FooPreviewComponent{
data: FooInterface;
constructor(
private _route: ActivatedRoute,
private _service: FooService) {
this._route.params
.switchMap(params=>
this._service.getFooById(params.id))//switchMap return type is Observable<FooInterface> because of the definition of getFooById
.subscribe(fooElement => this.data); //intellisense will detect the type of fooElement as FooInterface because of the return type of switchmap
}
}
在处理http的时间内,如果我们现在导航到root / foo / 1312313,则先前的请求将自动取消。
switchMap还有其他应用程序,但它需要对内部/外部可观察对象的某些内部有所了解。
您的解决方案效率低下,因为您正在订阅去抖动的输入值和由它们触发的http响应,但是当您真的只想订阅http响应时,您对第一个没有做任何事情。因此,您可以通过正确的方式使用switchMap来保存其中一个订阅。
答案 1 :(得分:-1)
我最终使用它并且它完美无缺。
this.searchTerms
.debounceTime(300)
.distinctUntilChanged()
.switchMap(
(term) => {
console.log('Term:' + term);
this.appRequestParams.appName = term;
this.fetchApps();
return term;
})
.subscribe();
}