Angular中如何在FormControl.valueChanges里按类型过滤实现自动搜索
问题:仅在值为字符串时触发API请求,过滤非字符串类型的流值
我有一段Angular代码,希望在searchControl.valueChanges的流中做过滤:只有当值是字符串类型时,才继续执行后续的服务器API请求;如果值不是字符串,就直接跳过,不发起请求。而且不想在switchMap里处理完整对象,要在过滤环节就完成拦截。
原代码片段:
this.searchControl.valueChanges.pipe( startWith(''), debounceTime(300), distinctUntilChanged(), filter((value) => typeof value === string) // 这里是我想做过滤的地方 tap(() => { this.errorMsg = ""; this.filteredSurveyItems = []; this.isLoading = true; }), switchMap(value => this.fetchOptions(value).pipe(finalize(() => { this.isLoading = false }),)) ).subscribe((data: any) => { if ( data ) { this.errorMsg = ""; this.filteredSurveyItems = data; } else { this.errorMsg = "No survey found..." this.filteredSurveyItems = []; } }); fetchOptions(value: string): Observable<Survey[]> { return this.surveySearchService.getSurveysByInput(value); }
修正方案
你当前的代码有个语法错误:typeof判断里的string需要加单引号,改成'string'。修正后这个filter操作符就会自动拦截所有非字符串类型的值,后续的tap和switchMap都不会执行,自然就不会发起API请求。
修正后的完整代码:
this.searchControl.valueChanges.pipe( startWith(''), debounceTime(300), distinctUntilChanged(), // 修正语法错误,正确判断字符串类型 filter((value) => typeof value === 'string'), tap(() => { this.errorMsg = ""; this.filteredSurveyItems = []; this.isLoading = true; }), switchMap(value => this.fetchOptions(value).pipe( finalize(() => { this.isLoading = false }) )) ).subscribe((data: any) => { if (data) { this.errorMsg = ""; this.filteredSurveyItems = data; } else { this.errorMsg = "No survey found..."; this.filteredSurveyItems = []; } }); fetchOptions(value: string): Observable<Survey[]> { return this.surveySearchService.getSurveysByInput(value); }
逻辑说明
- 当
searchControl的值是字符串(包括初始的空字符串'')时,会通过过滤,进入tap设置加载状态,再通过switchMap调用API获取数据 - 如果流中的值是其他类型(比如对象、数字、
null等),filter会直接把这个值过滤掉,后续的所有操作都不会触发,也就不会发起任何服务器请求
内容的提问来源于stack exchange,提问作者Usman
相关产品推荐
相关产品推荐

