如何检查 matInput 是否显示错误

发布于 2025-01-20 05:22:18 字数 2130 浏览 5 评论 0原文

我尝试显示错误消息和错误图标matinput具有错误时(由form> form concontrol控制)。 但是,如果表单是在没有触摸字段的情况下提交的,则不会显示错误。

或这是我的代码:

app.component.ts

ngOnInit() {
    this.formGroup = new FormGroup({
      email: new FormControl(null, [Validators.required, Validators.email]),
    });
}
get emailHasError() {
    return (
      !this.formGroup.get('email').valid && this.formGroup.get('email').touched
    );
}

app.component.html,

<form [formGroup]="formGroup" class="form">
  <mat-form-field class="form-element">
    <input matInput placeholder="Email address" formControlName="email" />
    <mat-error *ngIf="emailHasError">
      {{ errorEmail }}
    </mat-error>
  </mat-form-field>
  <div class="form-element">
    <button mat-raised-button color="primary" type="submit" class="button">
      Submit Form
    </button>
  </div>
</form>

但是,matinput字段变成红色,似乎会收到错误。

我阅读了一些建议,建议在表单提交上切换属性issubmit。但是似乎很丑陋,如果将表格分为几个组成部分,则需要将此属性传递给儿童组件。

Angular材料如何检测是否提交表单以显示错误?

编辑:

我目前发现的唯一解决方案是使用classList使用@viewchild如下。但这似乎仍然是一种骇人听闻的方法... 在Stackblitz上 我的处理如下:

@ViewChild('matInput') matInput: ElementRef;
get hasError() {
    return this.matInput?.nativeElement?.classList?.contains('ng-invalid');
}
<input
  matInput
  #matInput
  placeholder="Email address"
  formControlName="email"
/>

I try to display an error message and error icon when matInput has an error (controlled by a formControl).
But if the form is submited without touch the field, error is not displayed.

View code playground on stackblitz

Or here is my code:

app.component.ts

ngOnInit() {
    this.formGroup = new FormGroup({
      email: new FormControl(null, [Validators.required, Validators.email]),
    });
}
get emailHasError() {
    return (
      !this.formGroup.get('email').valid && this.formGroup.get('email').touched
    );
}

app.component.html

<form [formGroup]="formGroup" class="form">
  <mat-form-field class="form-element">
    <input matInput placeholder="Email address" formControlName="email" />
    <mat-error *ngIf="emailHasError">
      {{ errorEmail }}
    </mat-error>
  </mat-form-field>
  <div class="form-element">
    <button mat-raised-button color="primary" type="submit" class="button">
      Submit Form
    </button>
  </div>
</form>

However, the matInput field turns red and seems to receive the error.

I read some solution that suggests to toggle a property isSubmit on form submit. But seems to be ugly and and this requires passing this property to the child component if the form is split into several components.

How does Angular Material manage to detect if the form is submitted in order to display the error?

EDIT:

The only solution I found for now is to check classList with @ViewChild as follow. But it still seems to be a hacky way...
On stackblitz
I process as follow:

@ViewChild('matInput') matInput: ElementRef;
get hasError() {
    return this.matInput?.nativeElement?.classList?.contains('ng-invalid');
}
<input
  matInput
  #matInput
  placeholder="Email address"
  formControlName="email"
/>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

人疚 2025-01-27 05:22:19

无需返回 emailHasError()errorEmail(),并检查触摸内部组件,角度材料输入字段会自动检查并显示 mat-error 仅当某个字段被触摸时。

相反,直接检查 html 中的错误并相应地显示消息。

请参阅此处

在 styles.css 中添加此 css,以便在有多个错误时仅显示第一个错误 -

/* shows only first error */
.mat-error:not(:first-of-type) {
  display: none !important;
}

No need to return emailHasError() and errorEmail(), and checking touched inside component, angular material input field automatically checks that and shows mat-error only if a field is touched.

Instead directly check errors in html and show the message accordingly.

See working demo here

Added this css in styles.css to show only first error if there are more than one -

/* shows only first error */
.mat-error:not(:first-of-type) {
  display: none !important;
}
沉溺在你眼里的海 2025-01-27 05:22:19

自定义 error statateMatcher 解决这个问题的整洁解决方案。

  1. 创建一个自定义错误StateMatcher类似:
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)
    );
  }
}
  1. 将其添加到组件类中
  matcher = new MyErrorStateMatcher();
  1. ,将其添加到模板中。
  <mat-form-field class="form-element">
    <input
      matInput
      placeholder="Email address"
      formControlName="email"
      [errorStateMatcher]="matcher"
    />
    <mat-error *ngIf="formGroup.invalid">
      <mat-icon mat-suffix color="warn">error</mat-icon>
      {{ errorEmail }}
    </mat-error>
  </mat-form-field>

错误StateMatcher控制哪种条件应在UI中显示错误响应。在当前示例中,即使表单控件不是“肮脏”或“触摸”的,它也会在iSSUBITINES为TRUE时显示。

这是 stackblitz demo 。

A custom ErrorStateMatcher may be a neat solution for this problem.

  1. Create a custom ErrorStateMatcher like so:
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)
    );
  }
}
  1. Add it to your component class
  matcher = new MyErrorStateMatcher();
  1. Use it in your template
  <mat-form-field class="form-element">
    <input
      matInput
      placeholder="Email address"
      formControlName="email"
      [errorStateMatcher]="matcher"
    />
    <mat-error *ngIf="formGroup.invalid">
      <mat-icon mat-suffix color="warn">error</mat-icon>
      {{ errorEmail }}
    </mat-error>
  </mat-form-field>

The ErrorStateMatcher controls exactly which set of conditions should display an error response in the UI. In the current example, it will display whenever isSubmitted is true, even if the form control is not "dirty" or "touched".

Here's a stackblitz demo.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文