如何在输入字段中添加验证,以使多个输入字段不应该是相同的值?

时间:2018-03-31 12:43:57

标签: angular typescript angular-forms

我在html中重复了角度素材的输入字段,因此我使用<div *ngFor="let distanceVal of distanceArray;let i=index" layout-gt-xs="row"> <div flex="30" flex-offset="15"> <mat-form-field > <input matInput placeholder="Distance" type="number" [(ngModel)]="distanceVal.distance" name="distance{{i}}" (change)="distValCheck(distanceVal.distance,i,$event)" required class="number_type_style"> <mat-error *ngIf="routecheckValue || distanceVal.distance == null">{{ getErrorMessage(distanceVal.distance)}}</mat-error> <mat-error *ngIf="routecheckValue">This distance is already added </mat-error> <mat-error *ngIf="distanceVal.distance == null">This field is required</mat-error> </mat-form-field> </div> </div>来显示错误消息。

我实际上是在我的代码中使用模板驱动的表单,看看我到目前为止创建的输入字段的表单:

&#13;
&#13;
<mat-error>
&#13;
&#13;
&#13;

我实际上是在尝试验证输入字段,这样如果它在任何其他输入字段中找到任何相同的值,则mat-error应该显示在值相同的输入字段的正下方。

但是这里我的*ngIf只有在表单无效时才会被执行,并且没有使用我使用 background-color: deepskyblue!important; color: white!important; 编写的if条件执行

但是从前一个和下一个输入字段中获取重复值不会使表单无效,因为它是内置验证程序。

现在当我在其他输入字段中找到相同的值时,我应该如何显示mat-error

我没有发布ts文件的代码,因为我认为没有必要

3 个答案:

答案 0 :(得分:1)

如果要对兄弟控件进行验证,则需要将验证器提高一级。在控件周围创建一个包装器表单组,并在那里添加验证器。

像这样:

import { Component } from '@angular/core';
import {ValidatorFn, FormControl, FormGroup, FormBuilder, ValidationErrors } from '@angular/forms';

const DuplicateValueValidator: ValidatorFn = (ctrl: FormGroup) => {
  const first = ctrl.get('first').value;
  const second = ctrl.get('second').value;
  const third = ctrl.get('third').value;

  const hasDuplicates = new Set([first, second, third]).size < 3

  return hasDuplicates  ? {
    duplicateValue: 'duplicate values between controls'
  } : null
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  form: FormGroup;

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      first: ['one'],
      second: ['one'],
      third: ['three']
    }, { validator: DuplicateValueValidator})
  }
}

app.component.html

<form [formGroup]="form">
    <input formControlName="first" />
    <input formControlName="second" />
    <input formControlName="third" />

  {{ form.hasError('duplicateValue') ? form.getError('duplicateValue') : 'Valid' }}
</form>

Live demo

答案 1 :(得分:0)

要做到这一点:

  1. 创建控制器标志
  2. 在每个输入字段中,添加(keyup)事件
  3.   

    app.component.ts

        hasDuplicates = false;
    
        validateDuplicity() {
            const setOfDistances = new Set(this.distanceArray.map(distanceVal => distanceVal.distance));
            this.hasDuplicates = setOfDistances.size !== this.distanceArray.length;
        }
    
      

    app.component.html

    <input matInput 
           (keyup)="validateDuplicity()" 
           placeholder="Distance" 
           type="number"
           [(ngModel)]="distanceVal.distance" 
           name="distance{{i}}" 
           required
           class="number_type_style">
    

    然后,你应该使用

       <mat-error *ngIf="hasDuplicates">This distance is already added</mat-error>
    

答案 2 :(得分:0)

我将发布我写的一个验证器:

它是自定义的Morethan或相同的验证器。

import {Directive, ElementRef, AfterViewInit, OnChanges} from '@angular/core';
import {AbstractControl, NG_VALIDATORS, Validator} from '@angular/forms';
import {ValidationMessageType} from './validation-message';
import {AbstractValidator} from "./abstract-validator";

@Directive({
    selector: '[moreThanOrEqualNumberValidator][ngModel]',
    providers: [{provide: NG_VALIDATORS, useExisting: 
MoreThanOrEqualNumberValidatorDirective, multi: true}],
    inputs: ['minNumber']
})
export class MoreThanOrEqualNumberValidatorDirective extends AbstractValidator implements Validator, AfterViewInit, OnChanges{

minNumber:number;//input

ngOnChanges(){
    this.updateValidation();
}

ngAfterViewInit(){

}

updateValidation(){
    if(this.control){
        this.control.updateValueAndValidity();
    }
}

validate(control: AbstractControl): {[key: string]: any} {
    return this.moreThanNumberValidator(control);
}

 moreThanNumberValidator(control:AbstractControl):{[key:string]:any} {
    if (!this.isTouched()) {
        return null;
    }

    if (!this.activated) {
        return null;
    }

    if (isNaN(control.value) || control.value < this.minNumber) {
        return {'moreThanOrEqualNumber': {value: null}};
    }
    return null;
}
}

我在模板驱动的表单中使用它:

<input class="form-control" type="text" [(ngModel)]="alert.operand2" name="operand2" placeholder="قيمة الشرط" moreThanOrEqualNumberValidator [minNumber]="0"/>

我希望这会帮助你找到自己写的方式:)。