angular - 表单控件不适用于 Angular Material Mat-select
问题描述
我有一个mat-select表单元素绑定到 FormControl 以进行验证。目标是如果未填写选择框(或未选择任何内容),则在元素下方给出一个错误框
但是,在不选择选择选项的情况下提交时,该表单是有效的,即使我有一个必需的选项。
<form [formGroup]="cityForm" (submit)="submit()">
<mat-form-field>
<mat-label>Select City</mat-label>
<mat-select [(ngModel)]="city.Id"
[formControl]="cityFormControl"
[errorStateMatcher]="matcher">
<mat-option *ngFor="let c of dropdowns.Cities"
[value]="c.Id">
{{c.Name}}
</mat-option>
</mat-select>
<mat-error *ngIf="cityFormControl.hasError('required')">
City is <strong>required</strong>
</mat-error>
控制器代码:
//Angular Imports
import { Component, Input, OnInit } from '@angular/core';
import { FormControl, FormGroup, FormGroupDirective, NgForm, Validators } from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material/core';
@Component({
...
})
export class CityComponent implements OnInit {
city: any = {};
dropdowns: any = {};
// Form Control Variables
matcher = new MyErrorStateMatcher();
cityFormControl = new FormControl('', [Validators.required]);
cityForm = new FormGroup({
city: this.cityFormControl
});
constructor() {
}
ngOnInit(): void {
this.dropdowns = [
{Id: 1, Name: "Toronto"},
{Id: 2, Name: "Chicago"}
];
}
submit(form : FormGroup): void {
if (form.valid == false) {
//doesn't get called
return;
}
return;
}
/** Error when invalid control is dirty, touched, or submitted. */
export class MyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
const isSubmitted = form && form.submitted;
return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
}
}
知道为什么所需的验证不起作用吗?
解决方案
您需要提供控件名称,然后通过在您定义的控件上调用 valid 让材质表单处理错误。
<form [formGroup]="cityForm" (submit)="submit()">
<mat-form-field>
<mat-label>Select City</mat-label>
<mat-select formControlName="cityFormControl" // Form group is set by form tag
[compareWith]="CompareCity"> // You need to define a compare method
<mat-option *ngFor="let c of dropdowns.Cities"
[value]="c.Id">
{{c.Name}}
</mat-option>
</mat-select>
<mat-error *ngIf="!cityForm.controls['cityFormControl'].valid && cityForm.controls['cityFormControl'].touched">
City is <strong>required</strong>
</mat-error>
比较函数看起来像这样:
public CompareCity(Param1: City, Param2: City) : boolean {
return Param1 && Param2 ? Param1.Id === Param2.Id : false;
}
推荐阅读
- c++ - C++:带有重载成员函数的 std::apply
- python - 为什么输入永远不会结束
- dataframe - 将 Hbase 扫描结果 RDD 转换为数据帧:java
- reactjs - React Native - 升级到 0.62.2 后无法构建 - 瑜伽 - 无法在项目“pods”的目标“Yoga”中打开文件
- excel - 检查两列都为真,如果是,则用数据填充第三列
- architecture - 在 Pivotal Cloud Foundry 上运行的 Spring Cloud Dataflow 可以将文件写入本地服务器吗?
- django - ModuleNotFoundError:没有名为“路由器”的模块
- swiftui - 在 onAppear 中使用 DispatchGroup
- docker - 创建容器的最佳方法
- javascript - 如何在 javascript/html/jquery 中修复我的表的标题