Angular2反应形式显示基于验证失败条件的错误消息

时间:2017-10-29 14:33:22

标签: angular validation angular-reactive-forms

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

我有这个字段并且应用了两个验证:

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

如何为每个验证显示验证错误消息?假设如果提交中没有任何内容,我想显示两个错误:
“最小长度为5”
“需要字段”

然后,如果你把东西放在里面,它应该只显示:
“最小长度为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中使用erorr显示:

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

4 个答案:

答案 0 :(得分:13)

您的代码仅检查表单控件是否脏并且无效。但是您想检查特定验证是否失败。因此,您需要传递额外的error参数(&#39;必需&#39;,&#39; minlength&#39;等),然后使用

form.get(field).hasError(error)

答案 1 :(得分:9)

我稍晚回答这个问题,但我发现了一个解决方案,它是我真正喜欢的角度材料模块的一部分。如果使用“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

答案 2 :(得分:1)

如果custome validator matchOther失败,您应该返回{matchOther:true}并检查form.get(field).hasError('matchOther');

答案 3 :(得分:0)

在模板中,您可以使用

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