Angular13加载报Cannot call a class as a function错误排查
问题根因
报错触发逻辑非常明确:你传入Angular表单校验器列表的SpaceValidator是ES6类的构造函数,本身不能作为普通函数直接调用,Angular执行校验时尝试直接运行这个传入值,就抛出了Cannot call a class as a function的原生错误。
你当前的写法有两个明显问题:
SpaceValidator.bind(this)只是给类构造函数绑定了this上下文,根本没有指向类内部写了实际校验逻辑的cannotContainSpace实例方法- Angular同步校验器要求传入的参数必须是符合
(control: AbstractControl) => ValidationErrors | null签名的函数,直接传类本身完全不符合接口约定。另外你已经写了Validators.pattern(/^\S*$/),这个正则本身就已经实现了禁止输入空格的逻辑,和自定义校验器的功能完全重复。
修复方案
方案1:直接移除冗余自定义校验器(推荐)
你写的内置pattern正则/^\S*$/本身就会匹配所有不含空白字符的输入,和你自定义的空格校验逻辑完全一致,直接删掉SpaceValidator相关配置即可正常运行:
number: ["", [Validators.pattern(/^\S*$/)]]
方案2:修正自定义校验器写法
如果需要保留自定义校验器,不要用类做无意义的包装,Angular官方推荐直接导出独立校验函数,修改space.validator.ts代码:
import { AbstractControl, ValidationErrors } from "@angular/forms"; export function cannotContainSpace(control: AbstractControl): ValidationErrors | null { // 加可选链避免控件初始值为null/undefined时报错 if ((control.value as string)?.indexOf(' ') >= 0) { return { cannotContainSpace: true } } return null; }
表单配置处直接引入函数传入校验数组即可,不需要加bind:
import { cannotContainSpace } from "./space.validator"; // 表单组配置 number: ["", [Validators.pattern(/^\S*$/), cannotContainSpace]]
方案3:必须保留类写法的特殊场景
如果你的校验器需要依赖其他服务、必须用类实现,要先实例化类,再传入实例上的校验方法,同时绑定正确的this指向:
// 组件类中先实例化校验器 private spaceValidator = new SpaceValidator(); // 表单配置 number: ["", [ Validators.pattern(/^\S*$/), this.spaceValidator.cannotContainSpace.bind(this.spaceValidator) ]]
普通无依赖的同步校验器不要用类封装,冗余的包装层除了引发这类调用错误,没有任何实际收益。
内容的提问来源于stack exchange,提问作者user8933490
相关产品推荐
相关产品推荐

