验证器不是角度中的函数

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

我创建了自己的指令,用于添加验证和删除基于指令输入参数的验证。当加载和表单字段值更改验证器无法进行验证时,我收到错误

 @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)
angular angular-directive angular-forms angular-validation angular-validator
1个回答
0
投票

这些对于

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);

Stackblitz 演示

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