How to display only single validation erorr at a t

2019-03-27 11:28发布

I have this code to which displaying errors on my form

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

But in case of thing has two errors in it the two error show up. Lets say if my input has 5 validators so 5 divs will show up which is not nice. How to display just one error div at a time?

5条回答
相关推荐>>
2楼-- · 2019-03-27 11:59

You can create a Custom Pipe that checks first error equals with specified error:

CUSTOM PIPE

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

You can have lots of error div but just one error will be shown:

// 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>
查看更多
虎瘦雄心在
3楼-- · 2019-03-27 12:04

Angular2 behind the scene checks the status of the control and reacts accordingly. So if you don't want to have more validation at a time, you can logically play with AND(&&) or/and OR(||) or/and NOT(!) operators.

查看更多
萌系小妹纸
4楼-- · 2019-03-27 12:12
<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>

You could create a reusable component for showing errors so you don't need to repeat this code again and again.

查看更多
甜甜的少女心
5楼-- · 2019-03-27 12:14

You could create a custom pipe to get the first element of the errors object of the validator:

@Pipe({
  name: 'first'
})
export class FirstKeyPipe {
  transform(obj) {
    var keys = Object.keys(obj);
    if (keys && keys.length>0) {
      return keys[0];
    }
    return null;
  }
}

This way you would be able to display only one error:

@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])]
    });
  }
}

See this plunkr: https://plnkr.co/edit/c0CqOGuzvFHHh5K4XNnA?p=preview.

Note: agreed with Günter to create a usable component ;-) See this article for more details:

查看更多
甜甜的少女心
6楼-- · 2019-03-27 12:14

If you have consistent markup for your error message blocks, then you can use css to display only the first message and hide the rest:

css

.message-block .error-message {
  // Hidden by default
  display: none;
}
.message-block .error-message:first-child {
  display: block;
}

markup

<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>
查看更多
登录 后发表回答