Validation 如何一次仅显示一个验证错误

Validation 如何一次仅显示一个验证错误,validation,angular,angular2-forms,Validation,Angular,Angular2 Forms,我有一段代码,在我的表单上显示错误 <input [ngFormControl]="form1.controls['thing']" type="text" id="thing" #thing="ngForm"> <div *ngIf='thing.dirty && !thing.valid'> <div class="err" *ngIf='thing.errors.required'> Thing is requir

我有一段代码,在我的表单上显示错误

<input [ngFormControl]="form1.controls['thing']" type="text" id="thing" #thing="ngForm">
<div *ngIf='thing.dirty && !thing.valid'>
    <div class="err" *ngIf='thing.errors.required'>
        Thing is required.
    </div >
    <div class="err" *ngIf='thing.errors.invalid'>
        Thing is invalid.
    </div >
</div>

这是必须的。
这东西是无效的。
但是如果
东西
有两个错误,则会显示两个错误。 假设我的输入有
5个验证器
,那么
5个div
就会显示出来,这不好。 如何一次只显示一个
错误div
<input [ngFormControl]="form1.controls['thing']" type="text" id="thing" #thing="ngForm">
<div *ngIf='thing.dirty && !thing.valid'>
    <div class="err" *ngIf='thing.errors.required'>
        Thing is required.
    </div >
    <div class="err" *ngIf='!thing.errors.required && thing.errors.ivalid'>
        Thing is invalid.
    </div >
</div>
这是必须的。 这东西是无效的。
您可以创建一个可重复使用的组件来显示错误,这样您就不需要一次又一次地重复此代码。

Angular2幕后检查控件的状态并做出相应的反应。因此,如果您不想一次进行更多验证,您可以在逻辑上使用
和(&&&)
或/和
或(| |)或(
或/和
非(!)
运算符

您可以创建一个自定义管道来获取验证器的errors对象的第一个元素:

@Pipe({
  name: 'first'
})
export class FirstKeyPipe {
  transform(obj) {
    var keys = Object.keys(obj);
    if (keys && keys.length>0) {
      return keys[0];
    }
    return null;
  }
}
这样,您将只能显示一个错误:

@Component({
  selector: 'my-app',
  template: `
    <form>
      <input [ngFormControl]="form.controls.input1">
      <div *ngIf="form.controls.input1.errors">
        <div *ngIf="(form.controls.input1.errors | first)==='required'">
          Required
        </div>
        <div *ngIf="(form.controls.input1.errors | first)==='custom'">
          Custom
        </div>
      </div>
    </form>
  `,
  pipes: [ FirstKeyPipe ]
})
export class MyFormComponent {
  constructor(private fb:FormBuilder) {
    this.form = fb.group({
      input1: ['', Validators.compose([Validators.required, customValidator])]
    });
  }
}
@组件({
选择器:“我的应用程序”,
模板:`
要求的
习俗
`,
管道:[FirstKeyPipe]
})
导出类MyFormComponent{
构造函数(私有fb:FormBuilder){
this.form=fb.group({
输入1:['',Validators.compose([Validators.required,customValidator])]
});
}
}
请参阅以下链接:

注意:同意甘特创建可用组件;-)有关更多详细信息,请参阅本文:


您可以创建一个
自定义管道
,用于检查第一个错误是否等于指定的错误:

自定义管道

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'equals'
})

export class Equals implements PipeTransform {

  transform(errors: any, error: any, args?: any): any {
    if (!errors)
      return false;

    const array = Object.keys(errors);
    if (array && array.length > 0)
      return errors[array[0]] === error;

    return false;
  }
}
您可以有很多错误div,但只会显示一个错误:

// input is form.controls.input1
<div *ngIf="input.errors | equals:input.errors.required">Required</div>
<div *ngIf="input.errors | equals:input.errors.maxlength">MaxLength</div>
<div *ngIf="input.errors | equals:input.errors.pattern">Pattern</div>
//输入为form.controls.input1
要求的
最大长度
图案

如果错误消息块具有一致的标记,则可以使用css仅显示第一条消息并隐藏其余消息:

css

加价


需要电子邮件(显示消息块的第一个子项)
无效的电子邮件格式(默认情况下隐藏错误消息)

这是可行的,您不必像上面的@Joes answer那样在模板中硬编码验证

Template:
    <input id="password" placeholder="Password" type="password" formControlName="password" [(ngModel)]="password"  [ngClass]="{'invalid-input': !formUserDetails.get('password').valid && formUserDetails.get('password').touched}">
          <div class="validation-container">
            <ng-container *ngFor="let validation of userValidationMessages.password">
              <div class="invalid-message" *ngIf="formUserDetails.get('password').hasError(validation.type) && formUserDetails.get('password').touched">
                {{validation.message}}
              </div>
            </ng-container>
          </div>

CSS:
    .validation-container div {
      display: none;
    }

    .validation-container div:first-child {
      display: block;
    }
模板:
{{validation.message}
CSS:
.validation container div{
显示:无;
}
.验证容器div:第一个子项{
显示:块;
}

您可以将此与结合起来,稍微清理一下。另外,
firstKey
可能是管道的一个更具描述性的名称。可能是最好的解决方案,它允许选择witch error更重要的显示方式。虽然这样做有效,但意味着您必须硬编码模板中的所有验证检查。或者
.message block。错误消息:not(:first child){display:none;}
。这样,您就不必重写CSS。
<div class="message-block">
  <span class="error-message" *ngIf="myForm.get('email').hasError('required')">
    Email is required (first-child of message block is displayed)
  </span>
  <span class="error-message" *ngIf="myForm.get('email').hasError('email')">
    Invalid email format (error message hidden by default)
  </span>
</div>
Template:
    <input id="password" placeholder="Password" type="password" formControlName="password" [(ngModel)]="password"  [ngClass]="{'invalid-input': !formUserDetails.get('password').valid && formUserDetails.get('password').touched}">
          <div class="validation-container">
            <ng-container *ngFor="let validation of userValidationMessages.password">
              <div class="invalid-message" *ngIf="formUserDetails.get('password').hasError(validation.type) && formUserDetails.get('password').touched">
                {{validation.message}}
              </div>
            </ng-container>
          </div>

CSS:
    .validation-container div {
      display: none;
    }

    .validation-container div:first-child {
      display: block;
    }