【问题标题】:Why should I use Validators.compose()?为什么我应该使用 Validators.compose()?
【发布时间】:2017-07-12 17:01:43
【问题描述】:

我想用多个验证器验证一个字段。
使用模块驱动方法,代码如下所示:

this.exampleForm = this.fb.group({
  date_start : [
    '',
    Validators.compose([
      Validators.required,
      Validators.pattern("[0-9]{2}-[0-9]{2}-[0-9]{4}")
    ])]
})

但我也可以在没有 Validators.compose() 的情况下编写此代码,例如:

this.exampleForm = this.fb.group({
  date_start : [
    '',
    [
      Validators.required,
      Validators.pattern("[0-9]{2}-[0-9]{2}-[0-9]{4}")
    ]
  ]
})

而且效果很好。我个人更喜欢第二个版本(没有compose),更少的代码和更好的可读性。这就引出了一个问题,我为什么要使用 Validators.compose()?

【问题讨论】:

  • 我猜这主要是出于历史原因。
  • 呵呵,我猜... 到目前为止,我发现这种历史方法无处不在(视频、博客...),这真的很奇怪,然后突然在 Angular Cookbook 上我发现我不需要它。
  • Forms 模块在 2016 年 7 月/8 月进行了一次大改造,并删除了 compose() 的要求,但我猜他们保留它是为了避免不必要地破坏现有代码并让用户感到困惑。
  • 哦,我想它可能是这样的。好吧,谢谢你的信息。 :)
  • 嗯...仍然需要在 FormArray 上添加 multiple validators (因为它的构造函数只接受单个 ValidatorFn 而不是 @987654326 @. 只有当他们合并这个pull request时才需要。

标签: angular angular2-forms angular2-formbuilder


【解决方案1】:

当我们创建new FormControl/FormGroup/FormArray(AbstractControl) - coerceToValidator 被调用。

function coerceToValidator(
    validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null): ValidatorFn|
    null {
  const validator =
      (isOptionsObj(validatorOrOpts) ? (validatorOrOpts as AbstractControlOptions).validators :
                                       validatorOrOpts) as ValidatorFn |
      ValidatorFn[] | null;

  return Array.isArray(validator) ? composeValidators(validator) : validator || null;
}

export function composeValidators(validators: Array<Validator|Function>): ValidatorFn|null {
  return validators != null ? Validators.compose(validators.map(normalizeValidator)) : null;
}

因此,在我们将验证器传递给 AbstractControl 之前,无需编写验证器。

6/13/16 从现在开始添加feat(forms): compose validator fns automatically if arrays,Validators.compose 是为了向后兼容。

【讨论】:

    【解决方案2】:

    我知道这是一个老问题,但它是在最近的搜索中出现的。

    您可能想要使用Validators.compose() 的主要原因是重用多个验证器。假设您要检查一个值是否介于 0 和 100 之间。第一次,您会这样写:

    this.form = this.fb.group({
      foo: [ 0, [ Validators.min(0), Validators.max(100)]]
    });
    

    现在假设您想在应用中的多个位置执行此操作。为避免代码重复,您可以通过简单地从现有验证器组合它来创建自己的验证器,公开它并在需要的任何地方重用它:

    // custom-validators.ts
    import { Validators } from '@angular/forms';
    export class CustomValidators {
      readonly betweenZeroHundred = Validators.compose([
        Validators.min(0),
        Validators.max(100),
      ]);
    }
    
    // form1 
    this.form = this.fb.group({
      foo: [ 0, [CustomValidators.betweenZeroHundred()]]
    });
    
    // form2
    this.form = this.fb.group({
      bar: [ 100, [CustomValidators.betweenZeroHundred()]]
    });
    
    

    现在,使用扩展运算符,您可以实现类似的结果,而无需 compose()

    export class CustomValidators {
      readonly betweenZeroHundred = [Validators.min(0), Validators.max(100)];
    }
    
    this.form = this.fb.group({
      bar: [ 100, [...CustomValidators.betweenZeroHundred, Validators.required]]
    });
    
    
    

    最终,问题在于哪种方法更适合您的团队和您的情况。

    【讨论】:

    • 为什么不在整个代码库中重用一个数组呢?我认为没有理由使用Validators.compose
    • 这也是我的第一个任务——只使用数组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-20
    • 2011-04-22
    • 2011-05-16
    • 2017-04-16
    • 2010-12-22
    • 2010-09-07
    相关资源
    最近更新 更多