我创建了自己的指令,用于添加验证和删除基于指令输入参数的验证。当加载和表单字段值更改验证器无法进行验证时,我收到错误
@Directive({
selector:[appdirective1],
providers:[{
provide:NG_VAILDATORS,
useExisting:forwardRef(()=>directiveName)
}]
});
export class directiveName implements OnChanges,OnInit{
@Input varName1="";
@Input varName2="";
@Input callBack1:()=>{}
@Input callBack2:()=>{}
constructor(private _injector:Injector){
}
validate1():ValidateFn{
return (control:AbstractControl):{[key:string]:any}|null =>{
//logic here
}
}
validate2():ValidateFn{
return (control:AbstractControl):{[key:string]:any}|null =>{
const obj1=this.callBack1();
//logic here
}
}
validate3():ValidateFn{
return (control:AbstractControl):{[key:string]:any}|null =>{
const obj1=this.callBack2();
//logic here
}
}
ngOnInit(){
const control=this._injector.get(NgControl);
control.control.setValidators(this.validate1);
if(this.varName1 !=="" && this.varName1 !== undefined){
control.control.setValidators(this.validate2);
}
if(this.varName2 !=="" && this.varName2 !== undefined){
control.control.setValidators(this.validate3);
}
control.control.updateValueAndValidity();
}
ngOnChanges(){
const control=this._injector.get(NgControl);
if(this.varName1 !=="" && this.varName1 !== undefined){
control.control.setValidators(this.validate2);
}
if(this.varName2 !=="" && this.varName2 !== undefined){
control.control.setValidators(this.validate3);
}
control.control.updateValueAndValidity();
}
}
}
在html文件中,我添加了指令选择器和输入参数
<input appdirective1 name="name2" [varName1]="success" [callBack1]="method1" />
<input appdirective1 name="name3" [varName2]="success" [callBack2]="method2"/>
组件文件中已经绑定了方法method1和method2。我需要在很多地方使用这个文件。
我收到如下错误:
TypeError : validator is not a function
at Forms.mjs
at Array.map(<anonymous>)
at executeValidators(forms.mjs:896:21)
at Forms.mjs
at Array.map(<anonymous>)
at executeValidators(forms.mjs:896:21)
at Formcontrol2._ComposedValidatorsFn(forms.mjs)
at Formcontrol2._runValidator(forms.mjs)
at Formcontrol2.updateValueandValidity(forms.mjs)
这些对于
NG_VAILDATORS
提供程序来说是不需要的,因为您是使用 setValidators
和 addValidators
以编程方式添加验证器。当我们想要自动装配验证器时,我们会使用此提供程序,但您的代码中并非如此。
要了解有关 NG_VALIDATORS 的更多信息,请尝试这篇 Angular 自定义表单控件:完整指南 文章。
您需要使用
setValidators
而不是 addValidators
,因为 setValidators
会替换您之前设置的验证器。
control?.control?.addValidators(this.validate1());
您应该始终为具有此指令的元素配置
ngModel
或 form control
,只有这样 NgControl
才存在可供使用。
<input appdirective1 name="name2" [varName1]="success" [callBack1]="method1" [formControl]="control" #controlRef="ngForm"/>
<input appdirective1 name="name3" [varName2]="success" [callBack2]="method2" [(ngModel)]="name" #modelRef="ngModel"/>
我将重复的指令代码制作成它自己的函数以防止代码重复。
import {
Component,
Directive,
OnChanges,
OnInit,
forwardRef,
Input,
Injector,
} from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import {
NG_VALIDATORS,
ValidatorFn,
AbstractControl,
ValidationErrors,
NgControl,
ReactiveFormsModule,
FormsModule,
FormControl,
} from '@angular/forms';
import { CommonModule } from '@angular/common';
@Directive({
selector: '[appdirective1]',
standalone: true,
})
export class directiveName implements OnChanges, OnInit {
@Input() varName1 = '';
@Input() varName2 = '';
@Input() callBack1!: (control: AbstractControl) => ValidationErrors | null;
@Input() callBack2!: (control: AbstractControl) => ValidationErrors | null;
constructor(private _injector: Injector) {}
validate1(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
//logic here
return control.value === 'Angular'
? {
invalidName: control.value,
}
: null;
};
}
validate2(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const obj1 = this.callBack1(control);
//logic here
return obj1;
};
}
validate3(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const obj1 = this.callBack2(control);
//logic here
return obj1;
};
}
ngOnInit() {
this.conditionallyAddValidators();
}
conditionallyAddValidators() {
const control = this._injector.get(NgControl);
control?.control?.addValidators(this.validate1());
if (this.varName1 !== '' && this.varName1 !== undefined) {
control?.control?.addValidators(this.validate2());
}
if (this.varName2 !== '' && this.varName2 !== undefined) {
control?.control?.addValidators(this.validate3());
}
control?.control?.updateValueAndValidity();
}
ngOnChanges() {
this.conditionallyAddValidators();
}
}
@Component({
selector: 'app-root',
standalone: true,
imports: [directiveName, ReactiveFormsModule, CommonModule, FormsModule],
template: `
<input appdirective1 name="name2" [varName1]="success" [callBack1]="method1" [formControl]="control" #controlRef="ngForm"/>
<br/>
{{controlRef.errors | json}}
<br/>
<hr/>
<input appdirective1 name="name3" [varName2]="success" [callBack2]="method2" [(ngModel)]="name" #modelRef="ngModel"/>
<br/>
{{modelRef.errors | json}}
<br/>
<hr/>
`,
})
export class App {
control = new FormControl('Angular');
name = 'Angular';
success = 'required';
method1(control: AbstractControl) {
const value = control?.value;
return value?.length <= 2
? {
minLength: true,
}
: null;
}
method2(control: AbstractControl) {
const value = control?.value;
return value?.length >= 10
? {
maxLength: true,
}
: null;
}
}
bootstrapApplication(App);