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

Angular中MatAutocomplete选中选项后未赋值给FormControl问题

Angular MatAutocomplete选中选项后输入框空白问题解决

问题现象

在Angular组件中使用MatAutocomplete结合地址搜索API实现自动补全,搜索时下拉选项正常显示,但选中任意选项后,mat输入框始终为空——尽管FormControl对应的表单对象中已经存在选中的值。尝试在onAddressSelected方法中手动设置address1的FormControl值,输入框依旧不显示内容。

原因分析

  1. displayWith函数逻辑错误:你的mat-option中[value]绑定的是address?.description(字符串类型),但displayWith函数却试图访问value?.description——字符串没有description属性,导致函数返回undefined,输入框因此显示空白。
  2. 冗余的onAddressSelected方法:MatAutocomplete选中选项时会自动将[value]的值同步到绑定的FormControl中,手动调用setValue属于重复操作,且无法解决displayWith的根本问题。

修复步骤

1. 修正displayWith函数

将displayWith函数改为直接返回传入的value(因为value已经是地址描述字符串):

displayWith(value: any) {
  return value; // 直接返回字符串值
}

如果后续需要绑定完整的AddressInfo对象而非字符串(比如要获取地址的其他字段),可以调整如下:

  • HTML中mat-option的[value]绑定完整对象:
<mat-option *ngFor="let address of addresses" [value]="address">
  <span><b>{{address.description}}</b> ({{address.postcode}})</span>
</mat-option>
  • 此时displayWith函数保持原有逻辑,返回对象的description属性:
displayWith(value: AddressInfo) {
  return value?.description;
}

2. 移除冗余代码

  • 删除TS中的onAddressSelected方法:
// 移除这个无用方法
onAddressSelected() {
  console.log(this.form.value);
  const address1 = this.form.value.address1;
  this.form.get("address1").setValue(address1);
}
  • 删除HTML中mat-autocomplete的(optionSelected)事件绑定:
<!-- 移除(optionSelected)="onAddressSelected()" -->
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayWith">

3. 确保变更检测正常(可选)

由于组件使用了ChangeDetectionStrategy.OnPush,在地址数据更新后已经调用了this.ref.markForCheck(),这部分无需修改。

修改后的关键代码示例

组件TS代码(核心部分)

// ... 其他代码保持不变

ngOnInit() {
  this.form.get("address1").valueChanges
    .pipe(
      filter(res => res !== null && res.length >= this.minLengthTerm),
      distinctUntilChanged(),
      debounceTime(1000),
      tap(() => {
        this.ref.markForCheck();
        this.addresses = [];
        this.loadingMsg = "Loading....";
      }),
      switchMap(value => this.apiService.getAddressSuggestions(value)
        .pipe(finalize(() => this.loadingMsg = null))
      )
    )
    .subscribe((data: AddressInfo[]) => {
      this.addresses = data;
      this.loadingMsg = null;
      this.ref.markForCheck();
    });
}

// 修正后的displayWith
displayWith(value: any) {
  return value;
}

// ... 其他代码保持不变

HTML代码(核心部分)

<mat-form-field fxFlex="100" appearance="outline" floatLabel="always">
  <mat-label>Address Line 1</mat-label>
  <input matInput placeholder="Address Line 1" [formControlName]="'address1'" [matAutocomplete]="auto" />
  <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayWith">
    <mat-option *ngIf="loadingMsg" class="is-loading">{{loadingMsg}}</mat-option>
    <ng-container *ngIf="!loadingMsg">
      <mat-option *ngFor="let address of addresses" [value]="address?.description">
        <span><b>{{address.description}}</b> ({{address.postcode}})</span>
      </mat-option>
    </ng-container>
  </mat-autocomplete>
  <mat-error>Address Line 1 is {{this.getError('address1')}}</mat-error>
</mat-form-field>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 14:55:01