Angular6 Material - 使用带有自定义 ErrorStateMatcher 的输入的 Stepper

Posted

技术标签:

【中文标题】Angular6 Material - 使用带有自定义 ErrorStateMatcher 的输入的 Stepper【英文标题】:Angular6 Material - using Stepper with Input with a custom ErrorStateMatcher 【发布时间】:2019-01-24 17:18:22 【问题描述】:

这看起来应该很简单......在步进器中,您正在收集信息,并且您想确保电子邮件是电子邮件。但似乎共享的“表单”标签会导致错误检查器出现问题并且无法正常工作?

进一步澄清...问题似乎实际上在以下标记元素中...

     formControlName="emailCtrl"

当我删除此行并从 .ts (emailCtrl: ['', Validators.required],) 中删除它的同级行时,错误检查开始工作。但是,这意味着步进器无法验证是否需要此步骤。

如何确保步进器验证条目,同时确保 ErrorStateMatcher 正常工作?

这是我的组合 html...

<mat-step [stepControl]="infoFormGroup">
    <form [formGroup]="infoFormGroup">
        <ng-template matStepLabel>Profile Information</ng-template>

        <div>
            <!-- <form class="emailForm"> -->
                <mat-form-field class="full-width">
                    <input matInput placeholder="Username" [formControl]="emailFormControl" 
                        formControlName="emailCtrl"
                        [errorStateMatcher]="infoMatcher"> 
                    <mat-hint>Must be a valid email address</mat-hint>
                    <mat-error *ngIf="emailFormControl.hasError('email') && !emailFormControl.hasError('required')">
                        Please enter a valid email address for a username
                    </mat-error>
                    <mat-error *ngIf="emailFormControl.hasError('required')">
                        A username is <strong>required</strong>
                    </mat-error>
                </mat-form-field>
            <!-- </form> -->
        </div>

        <button mat-button matStepperPrevious>Back</button>
        <button mat-button matStepperNext>Next</button>

    </form>
</mat-step>

如您所见,我已经注释掉了电子邮件槽的嵌套“表单”。在测试中,我尝试将其注释掉而不是注释掉。无论哪种方式,错误检查都无法正常工作。

这里有一些相关的.ts sn-ps...

import  FormControl, FormGroupDirective, NgForm, Validators  from '@angular/forms';
import  FormBuilder, FormGroup  from '@angular/forms';
import  ErrorStateMatcher  from '@angular/material/core';
export class Pg2ErrorStateMatcher 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));
  

  ...
export class Pg2Dialog 
  ...

  emailFormControl = new FormControl('', [
    Validators.required,
    Validators.email,
  ]);

  infoMatcher = new Pg2ErrorStateMatcher();
  ...
    this.infoFormGroup = this._formBuilder.group(
      emailCtrl: ['', Validators.required],
    );

【问题讨论】:

我越来越接近了解潜在问题。似乎是formControlName和[formControl]的共存。即使我将它们命名为相同的东西,它也不起作用。但是,当 formControlName 存在并且更重要的是在 .ts 中定义时(例如... emailCtrl: ['', Validators.required]),它会混淆输入字段的错误检查。但是当我在两个地方都删除它们时,错误检查有效,但强制验证无效 【参考方案1】:

我相信我想通了。 ErrorStateMatcher 需要一个命名的表单控件。在这种情况下,它是 emailFormControl。声明如下...

  emailFormControl = new FormControl('', [
    Validators.required,
    Validators.email,
  ]);

此外,步进器需要一个命名的表单组,它本身声明了一个新的表单控件。在这种情况下,它是 emailCtrl。声明如下...

    this.infoFormGroup = this._formBuilder.group(
      emailCtrl: ['', Validators.required],
    );

要让步进表单控件使用 ErrorStateMatcher 表单控件,只需将方括号放在 .group 分配中,然后将 emailFormControl 分配给 emailCtrl。像这样……

    this.infoFormGroup = this._formBuilder.group(
      emailCtrl: this.emailFormControl
  );

我在一个不同的代码段中测试了这个,有类似的问题,它在两个地方都有效!

【讨论】:

以上是关于Angular6 Material - 使用带有自定义 ErrorStateMatcher 的输入的 Stepper的主要内容,如果未能解决你的问题,请参考以下文章

如何使用带有 material-ui 图标组件的自定义 SVG 文件?

使用带有 Material UI 的自定义主题在文本字段上指定悬停边框颜色

带有自定义组件的 Material ui 文本字段和 Formik 表单

angular6.x--虚拟滚动

如何在 Angular 6 中使用 Material 将 mat-chip 绑定到 ngmodel

Angular 6 Material - 等待 Mat 对话框关闭