Angular 12 mat-select选项渲染正常但无法选中问题求助
Angular 12.1 mat-select点击选项无响应排查
问题概况
- 基于Angular 12.1开发表单组件,使用Angular Material的
<mat-select>控件 - 通过服务异步获取数据,用
*ngFor渲染<mat-option>选项,选项显示正常,但点击后无任何反应 - 表单因该必填项为空始终处于无效状态
- 已尝试异步数据加载、移除翻译服务、改用formGroup等方法,问题未解决
相关代码
component.html
<div class="row"> <div class="col-md-10"> <h2>{{ "general.add" | translate }} {{ "general.distributionCenter" | translate }}</h2> </div> </div> <div class="row"> <form #form class="form col-md-10" fxLayout="column" fxLayoutAlign="center center" (ngSubmit)="onSubmit(form)"> <div class="row"> <div class="col-md-4"> <mat-form-field appearance="outline" class="w-100"> <mat-label>{{ "distributionCenters.name" | translate }}</mat-label> <input matInput [(ngModel)]="dc.name" name="name" #name="ngModel" required> </mat-form-field> </div> <div class="col-md-4" *ngIf="countriesReady === true"> <mat-form-field appearance="outline" class="w-100"> <mat-label>{{ "general.country" | translate }}</mat-label> <mat-select [(ngModel)]="selectedCountry" name="selectedCountry" required> <mat-option *ngFor="let country of countries" [value]="country.value"> {{ 'countries.' + country.displayValue | translate }} </mat-option> </mat-select> </mat-form-field> </div> </div> </form> <div class="col-md-2"> <button type="submit" mat-raised-button class="w-100" color="primary">{{ "general.add" | translate }}</button> </div> </div>
component.ts
import { AfterViewInit, Component, OnInit } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { DistributionCenter } from 'src/app/interfaces/distribution-center'; import { ParamService } from 'src/app/services/params.service'; @Component({ selector: 'app-create-distribution-center', templateUrl: './create-distribution-center.component.html', styleUrls: ['./create-distribution-center.component.scss'] }) export class CreateDistributionCenterComponent implements OnInit, AfterViewInit { countries: any; regions: any; communes: any; companies: any; dc: DistributionCenter = { name: '', address: '', regionId: '', communeId: '', companyId: '', latitude: 0, longitude: 0 } selectedCountry: any; countriesReady: boolean = false; countriesArray: { value: string; displayValue: string; }[] = []; constructor( private translate: TranslateService, private paramService: ParamService ) { this.selectedCountry = null; } ngOnInit(): void { this.getCountries(); console.log(this.countries); } ngAfterViewInit(): void { this.getCountries(); console.log(this.countries); } onSubmit(form: any): void{ console.log(form.value); /* some logic */ } getCountries(){ this.paramService.getParams("country").subscribe((res: any) => { this.countries = res.params; this.countries.forEach(((c: any) => { this.countriesArray.push({ value: c._id, displayValue: c.config.name.toLowerCase() }) })); this.countriesReady = true; }) } getTranslation = (param: string) => { return this.translate.instant(`countries.${param.toLowerCase()}`); } }
问题排查及解决方案
1. 数据源绑定错误
模板中*ngFor遍历的是原始的countries对象,但你在订阅回调里把处理好的value/displayValue数据存入了countriesArray,原始countries中并不存在这两个属性,导致[value]="country.value"绑定的是undefined,点击选项时无法正确赋值给selectedCountry。
修复:模板中改为遍历处理后的countriesArray:
<mat-option *ngFor="let country of countriesArray" [value]="country.value"> {{ 'countries.' + country.displayValue | translate }} </mat-option>
2. 重复调用数据接口
ngOnInit和ngAfterViewInit中都调用了getCountries(),导致两次请求数据,countriesArray被重复填充,可能引发渲染异常。
修复:移除ngAfterViewInit中的getCountries()调用,只保留ngOnInit中的一次调用:
ngAfterViewInit(): void { // 移除this.getCountries(); console.log(this.countries); }
额外优化建议
- 将
selectedCountry初始值设为''而非null,避免与表单必填校验的初始状态冲突 - 添加
trackBy函数优化*ngFor渲染性能:
<mat-option *ngFor="let country of countriesArray; trackBy: trackById" [value]="country.value"> {{ 'countries.' + country.displayValue | translate }} </mat-option>
在component.ts中添加:
trackById(index: number, item: any): string { return item.value; }
内容的提问来源于stack exchange,提问作者Nicolás Acevedo
相关产品推荐
相关产品推荐

