【问题标题】:Angular Custom validator: why export function?Angular 自定义验证器:为什么要导出函数?
【发布时间】:2020-01-29 10:35:54
【问题描述】:

我正在 Angular 中迈出第一步,必须为模板表单中的数字字段制作自定义最大验证器。就是这样:

import {Directive, Input} from '@angular/core';
import {AbstractControl, NG_VALIDATORS, ValidationErrors, Validator, ValidatorFn} from '@angular/forms';

@Directive({
  selector: '[appMaximumValue]',
  providers: [{provide: NG_VALIDATORS, useExisting: MaximumValueDirective, multi: true}]
})
export class MaximumValueDirective implements Validator {
  @Input('appMaximumValue') maximumValue: number;

  constructor() {
  }

  validate(control: AbstractControl): ValidationErrors | null {
    return this.maximumValue ? maximumValueValidator(this.maximumValue)(control) : null;
  }
}

export function maximumValueValidator(minimum: number): ValidatorFn {
  return (control: AbstractControl): { [key: string]: any } | null => {
    return control.value > minimum ? {'maximumValue': {value: control.value}} : null;
  };
}

想了想发现不用导出功能也可以:

import {Directive, Input} from '@angular/core';
import {AbstractControl, NG_VALIDATORS, ValidationErrors, Validator, ValidatorFn} from '@angular/forms';

@Directive({
  selector: '[appMaximumValue]',
  providers: [{provide: NG_VALIDATORS, useExisting: MaximumValueDirective, multi: true}]
})
export class MaximumValueDirective implements Validator {
  @Input('appMaximumValue') maximumValue: number;

  constructor() {
  }

  validate(control: AbstractControl): ValidationErrors | null {
    return Number(control.value) > this.maximumValue ? {'maximumValue': {value: control.value}} : null;
  }
}

所以我的问题是,这个导出功能的原因是什么?

【问题讨论】:

  • 当在不同的组件/服务中注入类时,你可以使用它的方法。这就是您不需要导出 validate 方法的原因。

标签: angular angular7 customvalidator


【解决方案1】:

因为你导出了maximumValueValidator,你也可以通过导入函数直接在TS文件中使用验证器逻辑。

该指令只能在 HTML 文件中使用,因此对于您的表单的使用,它无需导出。

如果您出于某种原因想要在 TS 文件中使用验证,则可以导出 maximumValueValidator 函数,因为这是验证器的真正逻辑。

如果您也不打算在 TS 文件中进行此验证,则可以删除 maximumValueValidator 的导出。

【讨论】:

  • 嗯,在 .ts 文件中使用它的明显原因是一种反应形式......这很好地解释了它,谢谢
【解决方案2】:

如果要在多个地方使用验证器的逻辑,您可能需要导出函数。

此外,在您的情况下,您可以使用 内置 max validator,在Validators.max 下可用

@Directive({})
export class YourDirective implements Validator {
 @Input() maxValue: number

  ngOnChanges(changes: SimpleChanges): void {
    if ('maxValue' in changes) {
      this.createValidator();
    }
  }

  validate(control: AbstractControl): ValidationErrors | null {
    return this.validator ? this.validator(control) : null;
  }

  private createValidator(): void {
    this.validator = this.maxValue ? Validators.max(this.maxValue) : null;
  }
}

【讨论】:

    【解决方案3】:

    当你想在其他类或函数中使用特定类或特定函数时,“export”关键字是必要的。如果不导出,我们就无法导入这些类或函数。

    例如,

    export class HomeComponent {}

    export function ValidatorFunction {}
    

    在其他类中,你可以使用

    import { HomeComponent } from '/somelocation';

    import { ValidatorFunction } from '/somelocation';

    但是,当涉及到这个特定的场景时,你不需要导入它,因为它是一个静态方法。请参考下面的链接。 Static Methods and Angular 2 Services in JavaScript ES6

    【讨论】:

      【解决方案4】:

      您上面列出的示例基本上为两种不同的表单实现了验证器。

      如果您要使用template-driven forms,使用指令的方法很有用,而下面需要的功能是您想使用 .ts 文件控制表单,这意味着您要使用 reactive forms

      它们的工作方式不同,使用方式也完全不同。 而对于一种情况,你会有类似

      HTML:
      <input type="number" appMaximumValue="5" />
      

      你会选择

      HTML:
      <input type="number" formControlName="myControl" />
      
      ts:
      form = new FormGroup({
        'myControl': new FormControl(0, maximumValueValidator(5));
      });
      

      在反应形式的情况下。

      您可以在官方文档form validation中阅读更多相关信息

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-02-12
        • 2019-01-07
        • 1970-01-01
        • 2018-07-24
        • 2019-02-12
        • 2020-06-07
        • 2018-05-23
        相关资源
        最近更新 更多