You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular自定义名称重复校验求助:mat-error提示异常

Angular自定义重复名称校验问题修复

问题说明

在Angular中实现自定义校验:当输入的名称与TS文件中定义的学生对象数组内的名称重复时,mat-error显示“名称已存在”提示。当前校验逻辑存在问题,以下是修复方案。

原代码

app.html

<form [formGroup]="form">
  <div>
      <mat-form-field>
        <input
         matInput
         type="text"
         [formControl]="name"
         required
        />
        <mat-error *ngIf="name.hasError('required')">
          此项为必填项
        </mat-error>
        <mat-error *ngIf="name.hasError('validateName')">
          名称已存在
        </mat-error>
      </mat-form-field>
   </div>
</form>

app.ts

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators, AbstractControl, ValidationErrors } from '@angular/forms';

@Component({
  selector: 'app-formulario',
  templateUrl: './component.html',
  styleUrls: ['./component.scss'],
})
export class AdminMaintainerFormsDialogComponent implements OnInit{
  public form: FormGroup;
  public name: AbstractControl;
  public totalStudents: any =
  [
    {
      name: "Sandro",
      rol: "student"
    },
    {
      name: "Paola",
      rol: "student"
    }
  ];

  constructor( private fb: FormBuilder) { }

  ngOnInit() {
    this.start();
  }

  start() {
    this.form = this.fb.group({
      name: ['', Validators.compose([Validators.required, this.validateName ])]
    });
  }

  private validateName(control: AbstractControl): ValidationErrors | null {
    const names = this.totalStudents;
    let compareName;

    names.map(value => {
      compareName = value.name;
    })

    return compareName.test(control.value) ? null : {
      validateName: {
        valid: false
      }
    };
  }

}

问题分析

  • 遍历逻辑错误:用map遍历数组时,compareName最终只会被赋值为数组最后一个元素的名称,无法覆盖所有已存在的名称。
  • 方法使用错误:test()是正则表达式专属方法,但compareName是普通字符串,调用该方法会直接报错。
  • 校验逻辑颠倒:当前逻辑是输入值匹配单个名称时返回校验通过,与“重复则报错”的需求完全相反。
  • 控件未绑定:TS中的name控件未从表单实例中获取引用,导致HTML中的[formControl]="name"无法正确关联。

修复后的代码

app.ts

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators, AbstractControl, ValidationErrors } from '@angular/forms';

@Component({
  selector: 'app-formulario',
  templateUrl: './component.html',
  styleUrls: ['./component.scss'],
})
export class AdminMaintainerFormsDialogComponent implements OnInit{
  public form: FormGroup;
  public name: AbstractControl;
  public totalStudents: any =
  [
    {
      name: "Sandro",
      rol: "student"
    },
    {
      name: "Paola",
      rol: "student"
    }
  ];

  constructor( private fb: FormBuilder) { }

  ngOnInit() {
    this.start();
  }

  start() {
    this.form = this.fb.group({
      // 绑定this确保校验器能访问组件内的totalStudents
      name: ['', Validators.compose([Validators.required, this.validateName.bind(this) ])]
    });
    // 关联表单控件实例
    this.name = this.form.get('name');
  }

  private validateName(control: AbstractControl): ValidationErrors | null {
    const inputName = control.value?.trim().toLowerCase();
    // 空值直接返回,让必填校验生效
    if (!inputName) return null;

    // 检查输入名称是否在学生数组中存在
    const isDuplicate = this.totalStudents.some(student => 
      student.name.toLowerCase() === inputName
    );

    // 重复则返回错误标记,否则校验通过
    return isDuplicate ? { validateName: true } : null;
  }

}

补充说明

  • 绑定this:自定义校验器传入表单时必须用bind(this),否则无法访问组件内的totalStudents数组。
  • 大小写处理:代码中加入了toLowerCase()实现忽略大小写的校验,若需要严格区分大小写,可直接移除该方法。
  • 空值过滤:输入为空时直接返回null,避免干扰必填项的校验逻辑。

内容的提问来源于stack exchange,提问作者Emanuel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 17:09:44