【问题标题】:How to compose a validation to check if one of two fields is not empty?如何编写验证以检查两个字段之一是否不为空?
【发布时间】:2017-07-10 11:06:52
【问题描述】:

所以,在 myForm 中,有 2 个字段 name 和 email,我想添加验证以检查用户是否输入其中之一,它会通过验证; 如果两个字段都为 null 或为空,则失败。

如何组合这样的验证器来满足我的场景?

<form [formGroup]="myForm" novalidate (ngSubmit)="submit(myForm.value)">
<div class="row">
    <div class="col-md-2"></div>
    <div class="col-md-8">
        <div class="card">
            <div class="card-header my-contact-info">
                My Contact Info
            </div>
            <div class="card-block">
                <div class="row">
                    <div class="col-md-6">
                        <div class="form-group">
                            <label>Name:</label>
                            <small class="alert" *ngIf="!myForm.controls['name'].valid && myForm.controls['name'].touched">This field is required.</small>
                            <input type="text" class="form-control" formControlName="name">
                        </div>
                        <div class="form-group">
                            <label>Email:</label>
                            <small class="alert" *ngIf="!myForm.controls['email'].valid && myForm.controls['email'].touched">This field is required. Please input a valid email.</small>
                            <input type="text" class="form-control" formControlName="email">
                        </div>
                    </div>
                    <div class="col-md-6">

                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

    buildForm(): void {
    this.myForm = this._fb.group({
        'name': [null, Validators.compose([Validators.required, Validators.minLength(3)])],
        'email': [null, Validators.compose([Validators.required, Validators.email])]
    });
}

【问题讨论】:

  • 您可以使用 OR 条件在提交功能上检查此项。如果给出其中任何一个,则执行您的代码,否则会引发验证错误。

标签: angular angular4-forms


【解决方案1】:

我会为此创建一个自定义验证器,例如:

import {FormControl, FormGroup, ValidatorFn} from '@angular/forms';
import {Observable} from 'rxjs/Observable';

export const OneFilledOutValidator = (): ValidatorFn => {

  return (group: FormGroup): {[key: string]: boolean} => {

    const fields = [];

    for (const field in group.controls) {

      if (group.controls.hasOwnProperty(field)) {
        fields.push(group.get(field).value);
      }
    };

    const result = fields.filter(field => !!field);

    const valid = result.length !== 0;

    return valid ? null : {
      oneFilledOut: true
    };
  };
};

这基本上采用一个表单组并检查任何控件是否有值。

this.myForm = this._fb.group({
    'name': [null, [Validators.minLength(3)]],
    'email': [null, [Validators.email]]
}, OneFilledOutValidator); // I would wrap this in a CustomValidators constant

【讨论】:

  • @AluanHaddad 我只是举了一个简单的例子。没有必要对这种愚蠢的事情投反对票。
  • @AluanHaddad 快乐吗?
  • @AluanHaddad 以后可以自己编辑答案,添加第一条评论作为编辑说明。而不是低估整个答案,因为它确实误导了问题的作者。如果代码本身按预期工作,有时使用 any 没有任何问题。
  • @Chrillewoodz 虽然您提出了一个很好的一般案例,但我看到 Angular 社区中出现了很多糟糕的 TypeScript,以至于值得一票否决。 any 在推理上下文中几乎总是错误的。这也没有意义。为什么人们要编写更多代码,以便他们可以使用更差的工具并破坏使用 TypeScript 的目的?一般来说,我只从 Angular 用户那里看到这种废话,我认为这是因为框架鼓励误解什么是类型(例如,参见 interface Type 声明)
  • @AluanHaddad 我意识到这一点,并且有一些因素可以解释为什么有棱角的人在打字稿方面如此糟糕。但这与这个问题完全无关,所以我不会深入探讨。但是就像我说的那样,您始终可以编辑答案并启发答案的作者他或她做错了什么。我总是想知道我做错了什么,但不是以对一个完美的答案投反对票的形式。而是在一个更好的例子和解释中。 :)
猜你喜欢
  • 2014-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-23
  • 2020-10-23
  • 2013-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多