【问题标题】:Angular2 reactive forms show error messages based on validation fail conditionAngular2 反应式表单根据验证失败条件显示错误消息
【发布时间】:2018-04-10 14:45:12
【问题描述】:

我想提一下,我使用单独的通用组件来显示错误,所以我没有将它们直接放在 html 中以避免重复,所以我不能直接在模板中链接和硬编码条件。

我已经应用了这个字段和两个验证:

this.username = new FormControl('', [ Validators.minLength(5), Validators.required ]); 

如何显示每个验证的验证错误消息?假设我想在提交时显示两个错误:
“最小长度为 5”
“必填字段”

然后如果你在里面放一些东西,它应该只显示:
"Minimum length is 5"

这是一个示例,但我的实际示例是比较两个电子邮件字段,如果它们相同,那么如果电子邮件不正确应该显示:
“电子邮件不正确”
“电子邮件与第一个电子邮件字段不同”

因此,如果电子邮件正确且电子邮件不相同,则应仅显示:
“电子邮件与第一个电子邮件字段不同”

如果没有通过,我有验证工作,但我不确定如何分别显示一个验证是否通过而另一个验证没有通过,因为我必须正确附加它失败的真正原因,而不是为两者提供一些通用原因。

完整示例:

错误显示组件:

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-field-error-display',
  templateUrl: './field.error.display.component.html',
  styleUrls: ['./field.error.display.component.css']
})
export class FieldErrorDisplayComponent
{
    @Input() errorMsg: string;
    @Input() displayError: boolean;
}

组件html:

<div *ngIf="displayError" >
  <small>{{errorMsg}}</small>
</div>

Register.html中错误显示的使用:

<form [formGroup]="_form" (ngSubmit)="register()">
<h4>Create a new account</h4>
<div class="form-group">
  <label for="email">Email Address</label>
  <input class="form-control" name="email" formControlName="email" />
  <app-field-error-display [displayError]="formValidationService.IsFieldValid(_form,'email')" errorMsg="Please insert correct email"></app-field-error-display>
</div>
<div class="form-group">
  <label for="emailConfirm">Email Address Confirm</label>
  <input class="form-control" name="emailConfirm" formControlName="emailConfirm" />
  <app-field-error-display [displayError]="formValidationService.IsFieldValid(_form,'emailConfirm')" errorMsg="Please insert correct email"></app-field-error-display>
</div>
<div class="form-group">
  <label for="password">Password</label>
  <input class="form-control" name="password" formControlName="password" />
  <app-field-error-display [displayError]="formValidationService.IsFieldValid(_form,'password')" errorMsg="Please insert password"></app-field-error-display>
</div>
<button type="submit" class="btn btn-default">Create Account</button>
</form>
<div *ngIf="_registered" class="alert alert-success box-msg" role="alert">
  <strong>Account registered!</strong> You will be redirected in sec
</div>

注册组件:

ngOnInit() {
    this._form = this._formBuilder.group({
        email: ['', [Validators.required, Validators.email]],
        emailConfirm: ['', [Validators.required, Validators.email, MatchOtherValidator.Validate('email')]],
        password: ['', [Validators.required]]
    });

    this._registerModel = new RegisterModel();
}

自定义匹配其他验证器:

import { FormControl } from '@angular/forms';

export class MatchOtherValidator {
    static Validate(otherControlName: string) {

        let thisControl: FormControl;
        let otherControl: FormControl;

        return function matchOtherValidate(control: FormControl) {

            if (!control.parent) {
                return null;
            }

            // Initializing the validator.
            if (!thisControl) {
                thisControl = control;
                otherControl = control.parent.get(otherControlName) as FormControl;
                if (!otherControl) {
                    throw new Error('matchOtherValidator(): other control is not found in parent group');
                }
                otherControl.valueChanges.subscribe(() => {
                    thisControl.updateValueAndValidity();
                });
            }

            if (!otherControl) {
                return null;
            }

            if (otherControl.value !== thisControl.value) {
                return {
                    matchOther: true
                };
            }

            return null;

        }
    }
}

表单验证服务有这个方法:

public IsFieldValid(form: FormGroup, field: string){
    return !form.get(field).valid && form.get(field).dirty;
}

【问题讨论】:

  • angular.io/guide/form-validation#built-in-validators: *ngIf="username.errors.minlength", *ngIf="username.errors.required"。
  • 不能直接链接到模板中。
  • 您将第一个条件放在显示最小长度消息的元素上,将第二个条件放在显示所需消息的元素上。如我链接到的文档中所示。具体问题是什么?你的代码在哪里?
  • 我添加了代码希望有意义
  • 您似乎没有阅读我的评论。您的代码仅检查表单控件是否脏且无效。但是您想检查特定验证是否失败:例如,return form.get(field).dirty &amp;&amp; form.get(field).errors.required 以检查所需的验证。您不可能从 invalid 布尔值(只能为真或假)中知道哪个验证失败。

标签: angular validation angular-reactive-forms


【解决方案1】:

您的代码仅检查表单控件是否脏且无效。但是您想检查特定验证是否失败。所以你需要传递一个额外的error 参数('required'、'minlength'等),并使用

form.get(field).hasError(error)

【讨论】:

  • 还有一件事,如果我有自定义验证器没有显示,我尝试使用预构建验证器。正如您在 emailConfirm 中看到的那样,我有 MatchOtherValidator.Validate('email')] 并且方法已启动,如何在 hasError 中检查通过自定义验证器?
  • @AmelSalibasic 如果自定义验证器 matchOther 失败,您应该返回 {matchOther: true} 并检查 form.get(field).hasError('matchOther');
【解决方案2】:

我回答这个问题有点晚了,但我找到了一个解决方案,它是我非常喜欢的角材料模块的一部分。如果您使用“mat-form-field”实现您的字段,您可以使用包含带有 *ngIf 的跨度的“mat-error”轻松显示错误消息。

我想我应该把它放在那里,以供其他尝试实现验证器错误消息的人使用。它使 HTML 有点健壮,但看起来确实不错。

<form [formGroup]="myForm" (ngSubmit)="submitForm()">
        <mat-form-field>
            <input matInput formControlName="user_input">
            <mat-error>
                <span *ngIf="myForm?.controls.user_input?.errors?.required">Required Field</span>
                <span *ngIf="myForm?.controls.user_input?.errors?.minLength">Minimum Length is 5</span>
            </mat-error>
        </mat-form-field>
</form>

文档可在此处找到:https://material.angular.io/components/form-field/overview#error-messages

【讨论】:

  • 请注意,mat-form-field 和 mat-error 不是内置于 angular 中的,它们是 单独的 Angular Material UI 包的一部分。 OP 没有提到他正在使用它。
  • @AlexanderAbakumov 不错。我会改变那里的措辞。
【解决方案3】:

如果自定义验证器 matchOther 失败,您应该返回 {matchOther: true} 并检查 form.get(field).hasError('matchOther');

【讨论】:

    【解决方案4】:

    在模板中可以使用

    <form class="example-form" [formGroup]="formName" (ngSubmit)="onFormSubmit()">
    
    <input matInput #inputName formControlName="inputName"
                  name="inputName" required/>
      <mat-error *ngIf="formName.get('inputName').hasError('required')">
            Email is <strong>required</strong>
      </mat-error>
    </form>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-17
      • 2019-03-13
      • 2017-05-12
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      • 2018-01-02
      相关资源
      最近更新 更多