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

Angular mat-autocomplete面板首次聚焦不展开问题求助

问题排查与解决方案

问题原因分析

  1. 异步数据加载与过滤流初始化时机冲突
    你的onFetchTPA是异步HTTP请求,searchFiltertpa在ngOnInit中直接调用时,tpaDetails还未被接口返回的数据赋值。此时filteredTPA流中startWith('')触发过滤逻辑时,this.tpaDetails.slice()返回空数组,导致面板无选项可展示,自然不会展开。

  2. mat-autocomplete默认无聚焦展开行为
    Angular Material的mat-autocomplete组件默认不会在输入框聚焦时自动打开面板,只有当输入框值变化(输入文本)时才会触发过滤流并展示面板。


解决方案

1. 同步异步数据与过滤流

使用BehaviorSubject包装tpaDetails,确保过滤流能监听数据加载完成后的更新:

修改class.ts代码:

import { BehaviorSubject, combineLatest } from 'rxjs';
import { map, startWith } from 'rxjs/operators';

// 新增BehaviorSubject用于监听tpa数据变化
private tpaDetailsSubject = new BehaviorSubject<any[]>([]);

onFetchTPA() {
    this.validation_dialog_box = true;
    this.fr_write_service.onFetchTPA().subscribe((data) => {
        const responseData = JSON.parse(data);
        this.tpaDetails = responseData?.sort((a, b) => {
            if (a.tpaName < b.tpaName) return -1;
            if (a.tpaName > b.tpaName) return 1;
            return 0;
        });
        // 将加载完成的数据发送到Subject
        this.tpaDetailsSubject.next(this.tpaDetails);
        this.validation_dialog_box = false;
    }, (error) => {
        this.errorPopup(error);
    });
}

searchFiltertpa(formDetails) {
    const tpaCntrl = formDetails.get('tpa');
    if (tpaCntrl) {
        // 结合输入框值变化和数据Subject的流
        this.filteredTPA = combineLatest([
            tpaCntrl.valueChanges.pipe(startWith('')),
            this.tpaDetailsSubject.asObservable()
        ]).pipe(
            map(([value, tpaList]) => {
                // 处理选中对象的情况,提取搜索关键词
                const searchTerm = typeof value === 'string' ? value : value?.tpaName || '';
                return searchTerm ? this.filtertpa(searchTerm, tpaList) : tpaList.slice();
            })
        );
    }
}

// 修改filtertpa方法,接收当前的tpa列表作为参数
filtertpa(tpaData: any, tpaList: any[]) {
    const arr = tpaList.filter(
        (tpa) => tpa.tpaName.toLowerCase().indexOf(tpaData.toLowerCase()) === 0
    );
    return arr.length ? arr : [{ tpaName: 'No Item found' }];
}

2. 添加聚焦触发面板展开逻辑

在输入框上绑定focus事件,手动调用面板的open()方法:

修改HTML代码:

<mat-form-field class="width">
  <input 
    type="text" 
    formControlName="tpa" 
    matInput 
    [matAutocomplete]="tpaAuto"
    (focus)="openPanel(tpaAuto)"
  />
  <mat-autocomplete #tpaAuto="matAutocomplete" [displayWith]="displayTpa.bind(this)">
    <mat-option *ngFor="let data of exportPdfInstance.filteredTPA | async" [value]="data">
      <span>{{ data.tpaName }}</span>
    </mat-option>
  </mat-autocomplete>
</mat-form-field>

在组件component.ts中添加openPanel方法:

import { MatAutocomplete } from '@angular/material/autocomplete';

// ...

openPanel(panel: MatAutocomplete) {
  panel.open();
}

3. 第二个autocomplete组件的适配

对第二个mat-autocomplete组件执行相同逻辑:

  • 用BehaviorSubject包装对应的数据列表
  • 修改其过滤方法为combineLatest模式
  • 在输入框上绑定(focus)="openPanel(xxxAuto)",传入对应的面板引用

内容的提问来源于stack exchange,提问作者Danny

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 21:09:51