Angular Material - 带电子邮件验证的芯片

问题描述 投票:0回答:1

我正在尝试创建一个带有输入的表单,使用芯片将消息发送到各种电子邮件。我的它几乎可以正常工作,但我不知道当您写了无效的电子邮件或不写任何内容时如何正确显示消息错误。

这是我的自定义验证器:

import { FormControl } from '@angular/forms';

const REGEXP_EMAIL =
  /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i;

export const emailsArrayValidator = (control: FormControl) => {
  const emails: string[] = Array.isArray(control.value) ? control.value : [];
  const invalidEmails = emails.filter(email => !REGEXP_EMAIL.test(email.trim()));
  return invalidEmails.length === 0 ? null : { invalidEmails: true };
};

这是component.ts

constructor(private fb: FormBuilder) {
  this.inviteForm = this.fb.group({
    name: ['', Validators.required],
    email: ['', [Validators.required, Validators.pattern(this.REGEXP_EMAIL)]],
    date: ['', Validators.required],
    friends: [[], [Validators.required, Validators.minLength(1), emailsArrayValidator]],
  });
}

get name() {
  return this.inviteForm.get('name') as FormControl;
}

get email() {
  return this.inviteForm.get('email') as FormControl;
}

get date() {
  return this.inviteForm.get('date') as FormControl;
}

get friends() {
  return this.inviteForm.get('friends') as FormControl;
}

addFriend(event: MatChipInputEvent) {
  const friendEmail = event.value.trim();

  const friends = [...this.friends.value, friendEmail];
  const validationErrors = emailsArrayValidator(new FormControl(friends));
  console.log(validationErrors);
  if (validationErrors) {
    this.friendsErrorMessage = 'The last email is not valid';
  } else {
    this.friendsErrorMessage = '';
    this.friends.setValue(friends);
  }

  event.chipInput!.clear();
}

removeFriend(email: string) {
  const friends = this.friends.value.slice();
  const index = friends.indexOf(email);
  if (index !== -1) {
    friends.splice(index, 1);
    this.friends.setValue(friends);
  }
}

这是 HTML:

<mat-form-field>
  <mat-label>Enter invitation email</mat-label>
  <mat-chip-grid #chipGrid>
    @for (friend of friends.value; track friend) {
      <mat-chip-row (removed)="removeFriend(friend)" [editable]="true">
        {{ friend }}
        <button matChipRemove>
          <mat-icon>cancel</mat-icon>
        </button>
      </mat-chip-row>
    }
    <input
      [matChipInputFor]="chipGrid"
      [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
      [matChipInputAddOnBlur]="addOnBlur"
      (matChipInputTokenEnd)="addFriend($event)"
      required
    /></mat-chip-grid>
    @if (friends.errors && friends.touched) {
      <mat-error>{{ friendsErrorMessage }}</mat-error>
    }
</mat-form-field>
angular typescript angular-material angular-reactive-forms angular-validation
1个回答
1
投票

您的问题与此 GitHub 问题类似:MatChipInput 的 mat-error 未显示在输入下

  1. 触发
    errorState = true
    显示错误消息。
  2. 通过
    friends
    设置
    <AbstractControl>.setErrors(/* ValidationError */)
    控制的误差。
  3. 通过
    friends
    <AbstractControl>.markAsTouched()
    控件标记为触摸,以根据您的情况显示错误消息:
    @if (friends.errors && friends.touched)

此外,对于之前输入无效邮箱的场景,您还应该重置

errorState
并消除验证错误,然后填写有效邮箱。

import {MatChipGrid} from '@angular/material/chips';

@ViewChild('chipGrid') chipGrid: MatChipGrid;

addFriend(event: MatChipInputEvent) {
  const friendEmail = event.value.trim();

  const friends = [...this.friends.value, friendEmail];
  const validationErrors = emailsArrayValidator(new FormControl(friends));
  console.log(validationErrors);
  if (validationErrors) {
    this.friendsErrorMessage = 'The last email is not valid';
    this.friends.setErrors(validationErrors, { emitEvent: false })
    this.chipGrid.errorState = true;
  } else {
    this.chipGrid.errorState = false;
    this.friends.setErrors({ invalidEmails: null });

    this.friendsErrorMessage = '';
    this.friends.setValue(friends);
  }

  this.friends.markAsTouched();
  event.chipInput!.clear();
}

演示@StackBlitz

© www.soinside.com 2019 - 2024. All rights reserved.