Observable异步数据源的Auto-complete自动补全过滤功能异常问题
问题分析与修复方案
核心错误点
- 过滤逻辑执行顺序错误:你在搜索过滤的逻辑之后,给
courses$追加了一个固定插入33、44的pipe,所有过滤后的结果都会被强制插入这两个值,这是输入不匹配内容时依然能看到33、44的直接原因。 - 循环引用数据流:在
switchMap中你直接引用了正在被重赋值的courses$本身,形成了逻辑死循环,原始数据源的过滤逻辑完全无法按照预期执行。 - 数据源构造逻辑错误:需要追加的固定值
33、44没有被纳入过滤的数据源范围,过滤逻辑只能匹配到原始的11、22两个值。
修复思路
先构造包含所有待搜索内容的完整数据源,再基于搜索关键词的变化对完整数据源做过滤,不要在过滤结束后再修改结果数组。
修正后代码
HTML代码(无需改动)
Search <input type="text" [formControl]="search"> <div *ngIf="(courses$ | async) as courses"> <pre>{{ courses | json }}</pre> </div>
组件TS代码
export class AppComponent { title = "CodeSandbox"; courses$: Observable<string[]>; search: FormControl = new FormControl(); // 完整的待搜索数据源,包含原始值和需要追加的值 private fullCourses$: Observable<string[]>; constructor() { // 提前构造完整数据源 this.fullCourses$ = this.getCourses$().pipe( map(courses => [...courses, '33', '44']) ); } public getCourses$(){ return of([ '11', '22' ]); } ngOnInit(){ // 直接基于搜索值变化对完整数据源做过滤 this.courses$ = this.search .valueChanges .pipe( startWith(''), switchMap(searchKey => { return this.fullCourses$.pipe( map(courses => { if (!searchKey) return courses; const lowerKey = searchKey.toLowerCase(); return courses.filter(course => course.toLowerCase().includes(lowerKey) ); }) ) }) ); } }
内容的提问来源于stack exchange,提问作者carlos
相关产品推荐
相关产品推荐

