Angular中MatAutocomplete选中选项后未赋值给FormControl问题
Angular MatAutocomplete选中选项后输入框空白问题解决
问题现象
在Angular组件中使用MatAutocomplete结合地址搜索API实现自动补全,搜索时下拉选项正常显示,但选中任意选项后,mat输入框始终为空——尽管FormControl对应的表单对象中已经存在选中的值。尝试在onAddressSelected方法中手动设置address1的FormControl值,输入框依旧不显示内容。
原因分析
displayWith函数逻辑错误:你的mat-option中[value]绑定的是address?.description(字符串类型),但displayWith函数却试图访问value?.description——字符串没有description属性,导致函数返回undefined,输入框因此显示空白。- 冗余的
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
相关产品推荐
相关产品推荐

