You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 12:36:04