【问题标题】:Cross Field Validation: Angular Reactive Form跨字段验证:角度反应形式
【发布时间】:2022-11-03 00:37:23
【问题描述】:

我的要求是根据其他字段的值来验证字段。我有 3 个字段 slaBeforeExpiry、slaAtExpiry 和 slaAfterExpiry。这些字段的值应按升序排列。

slaBeforeExpiry >= slaAtExpiry >= slaAfterExpiry

当我尝试按顺序填充值时,它工作正常。例如:

如果我在 slaBeforeExpiry 中填写值 2,在 slaAtExpiry 中填写 3。出现错误 div。如果我将它的 slaAtExpiry 值更改为小于 slaBeforeExpiry 错误 div 隐藏。但是,如果我没有减少 slaAtExpiry 的值,而是尝试增加 slaBeforeExpiry 的值大于 slaAtExpiry 错误 div 不会消失。

这只是第一次发生。

这是我的代码:

<form [formGroup]="slaForm">
<div class="form-group"> 
<label>Sla Before Expiry: </label>
<input autocomplete="off" matInput type="number" min="0" formControlName="slaBeforeExpiry">

</div>


<div class="form-group">
<label>Sla At Expiry: </label>
<input autocomplete="off" type="number" min="0"  matInput formControlName="slaAtExpiry">
<div class="error" *ngIf="slaForm.controls.slaAtExpiry.hasError('slaatexpiry') || slaForm.controls.slaBeforeExpiry.hasError('slaatexpiry')">SLA On Breach should be less than or equal to SLA Before Breach</div>
</div>


<div class="form-group">
<label>Sla After Expiry: </label>
<input autocomplete="off" type="number" min="0"  matInput formControlName="slaAfterExpiry">
<div class="error" *ngIf="slaForm.controls.slaAfterExpiry.hasError('slaafterexpiry')
 || slaForm.controls.slaAtExpiry.hasError('slaafterexpiry')">SLA After Breach should be less than or equal to SLA On Breach</div>
</div>

</form>

******** ts ********

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

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

  public slaForm: FormGroup = new FormGroup(
    {
      slaBeforeExpiry: new FormControl('', [Validators.required, this.validateSlaBeforeExpiry]),
      slaAtExpiry: new FormControl('', [Validators.required, this.validateSlaAtExpiry, this.validateSlaAfterExpiry2]),
      slaAfterExpiry: new FormControl('', [Validators.required, this.validateSlaAfterExpiry])
    }
  );

  public validateSlaBeforeExpiry (control: FormControl) :ValidatorFn{
    let isValid = null;
    if(control.value !== '' && control.parent.controls['slaAtExpiry'].value !== ''){
      if(control.value >= control.parent.controls['slaAtExpiry'].value ){
        isValid = null;
      }else{
        isValid = {'slaatexpiry': true}
      }
    }
    return isValid;
  }

/**
 * this method validates sla value before expiry is 
 * greater than or equal to sla at expiry
 * @param control 
 * @returns error
 */
 public validateSlaAtExpiry(control: FormControl):ValidatorFn{
  let isValid = null;
  if(control.value !== '' && control.parent.controls['slaBeforeExpiry'].value !== ''){
    if(control.parent.controls['slaBeforeExpiry'].value >= control.value){
      isValid = null;
    }else{
      isValid = {'slaatexpiry': true}
    }
  }
  return isValid;
}

/**
 * this method validates sla after expiry is less than
 * or equal to sla on expiry
 * @param control 
 * @returns error if 
 */
public validateSlaAfterExpiry(control: FormControl):ValidatorFn{
  let isValid = null;
  if(control.value !== '' && control.parent.controls['slaAtExpiry'].value !== ''){
    if(control.parent.controls['slaAtExpiry'].value >= control.value){
      isValid = null;
    }else{
      isValid = {'slaafterexpiry': true}
    }
  }
  return isValid;
}

public validateSlaAfterExpiry2(control: FormControl):ValidatorFn{
  let isValid = null;
  if(control.value !== '' && control.parent.controls['slaAfterExpiry'].value !== ''){
    if(control.value >= control.parent.controls['slaAfterExpiry'].value ){
      isValid = null;
    }else{
      isValid = {'slaafterexpiry': true}
    }
  }
  return isValid;
}
}

看起来我做错了什么。任何帮助将不胜感激。

Stackblitz 也一样:https://stackblitz.com/edit/angular-ivy-vzau71?file=src/app/app.component.ts

【问题讨论】:

  • 我建议不要在每个控件上使用验证器,而是在表单组上使用验证器。您可以根据需要在各个控件上设置错误SO answer
  • 它有效@AndrewAllen。非常感谢。它拯救了我的一天

标签: angular angular-reactive-forms


【解决方案1】:

当 BeforeExpiry 控件值有效时,您必须删除 slaAtExpiry 控件上的错误

control.parent.controls['slaAtExpiry'].setErrors({'slaatexpiry': false})

  public validateSlaBeforeExpiry (control: FormControl) :ValidatorFn{
    let isValid = null;
    if(control.value !== '' && control.parent.controls['slaAtExpiry'].value !== ''){
      if(control.value >= control.parent.controls['slaAtExpiry'].value ){
        isValid = null;
        control.parent.controls['slaAtExpiry'].setErrors({'slaatexpiry': false})

      }else{
        isValid = {'slaatexpiry': true}
      }
    }
    return isValid;
  }

【讨论】:

    【解决方案2】:

    如果有人遇到此问题,请发布答案:

    import { Component } from '@angular/core';
    import { FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
    
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: [ './app.component.css' ]
    })
    export class AppComponent  {
    
      public slaForm: FormGroup = new FormGroup(
        {
          slaBeforeExpiry: new FormControl('', [Validators.required]),
          slaAtExpiry: new FormControl('', [Validators.required]),
          slaAfterExpiry: new FormControl('', [Validators.required])
        },{ validators: this.customValidatorForm() },
      );
    
      public customValidatorForm(){
        return ((form:FormGroup)=>{
          let slaBeforeExpiry = form.get('slaBeforeExpiry').value;
          let slaAtExpiry = form.get('slaAtExpiry').value;
          let slaAfterExpiry = form.get('slaAfterExpiry').value;
          let error: any;
          if(slaBeforeExpiry < slaAtExpiry){
            form.get('slaAtExpiry').setErrors({'slaatexpiry': true})
          }else{
            form.get('slaAtExpiry').setErrors(null)
          }
          if(slaAtExpiry < slaAfterExpiry){
            form.get('slaAfterExpiry').setErrors({'slaafterexpiry': true})
          }else{
            form.get('slaAfterExpiry').setErrors(null)
          }
          return error;
        })
      }
      
    }
    

    堆栈闪电战:https://stackblitz.com/edit/angular-ivy-gd5uum?file=src/app/app.component.ts

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-28
      • 1970-01-01
      • 1970-01-01
      • 2020-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-25
      相关资源
      最近更新 更多