首页 > 解决方案 > 表单控件不适用于 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));
    }
}

知道为什么所需的验证不起作用吗?

标签: angulartypescriptangular-materialform-control

解决方案


您需要提供控件名称,然后通过在您定义的控件上调用 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;
  }


推荐阅读