【问题标题】:Angular Reactive Forms multiple custom validationsAngular Reactive Forms 多个自定义验证
【发布时间】:2018-08-09 15:32:57
【问题描述】:

我有一个自定义验证来检查一个数字是否在范围内,一个是否已经分配了一个数字。

代码(范围内的数字)

validateTagIdRange(control: AbstractControl) {
// tagId between 10000 and 39999
  return ((control.value >= 10000) && (control.value <= 39999)) ? null : { tagIdRange: true };
}

代码(已分配编号)

validateTagId(control: AbstractControl) {
  // is tagId already given?
  let result: number;
  this.userService.getAll().subscribe(
    res => result = res.findIndex(obj => obj['tagId'] === control.value)
  );
  return (result === -1) ? null : { tagIdExists: true };
}

代码(向表单控件添加自定义验证器)

  this.transponderForm = this.fb.group({
    tagId: ['', [this.validateTagIdRange.bind(this), this.validateTagId.bind(this)]],
  });

代码(在模板中)

  <mat-form-field class="example-full-width">
    <input matInput placeholder="Transponder-ID" type="number" formControlName="tagId">
    <mat-error *ngIf="transponderForm.controls.tagId.errors?.tagIdRange">Transponder ID must be between 10.000 and 39.999</mat-error>
    <mat-error *ngIf="transponderForm.controls.tagId.errors?.tagIdExists">Transponder ID is already assigned.</mat-error>
  </mat-form-field>

如果已经分配了 ID,则仅应显示来自 tagIdExists 的消息,当 ID 不在范围内时,仅应显示来自 tagIdRange 的消息。如何显示正确的错误信息?


验证器 TagIdInRange 现在正在工作,并在表单中显示他的错误消息。对于检查 tagId 是否已被使用的第二个验证器,它不会显示相关的错误消息。

FormComponent.ts

ngOnInit() {
  this.transponderForm = this.fb.group({
    tagId: ['', Validators.compose([this.validateTagIdRange(), this.validateTagId()])]
});

validateTagIdRange(): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    return ((control.value >= 10000) && (control.value <= 39999)) ? null : { tagIdInRange: true };
  };
}

validateTagId(): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    return this.userService.getAll()
      .map(res => (res.findIndex(obj => obj['tagId'] === result) === -1) ? null : { tagIdExists: true });
  };
}

FormComponent.html

<form [formGroup]="transponderForm">
  <mat-form-field class="example-full-width">
    <input matInput placeholder="Transponder-ID" type="number" formControlName="tagId">
    <mat-error *ngIf="transponderForm.get('tagId').hasError('tagIdInRange')">Die Transponder ID muss im Bereich 10.000 und 39.999 liegen.</mat-error>
    <mat-error *ngIf="transponderForm.get('tagId').hasError('tagIdExists')">Die Transponder ID ist bereits vorhanden.</mat-error>
  </mat-form-field>
</form>

在 app.module.ts 中导入 ReactiveFormsModule。

【问题讨论】:

    标签: angular angular-material angular-reactive-forms


    【解决方案1】:

    不要以这种方式订阅验证器,否则会导致内存泄漏。在表单中最好使用 Smart/Dumb Components 模式并将您的 observable 作为 @input 发送到您的 Dumb Components Explanation of pattern

    在您的 FormGroup 中使用 Validators.compose 并传入您在 Dumb 组件中输入的 taglist

    this.transponderForm = this.fb.group({
          'tagId': ['', Validators.compose([this.validateTagIdRange(), this.validateTagId(this.taglist )])]
      });
    

    您的验证函数将如下所示:

     validateTagId(taglist: any[]): ValidatorFn {
        return (control: AbstractControl): ValidationErrors | null => {
          const inputValue = control.value;
          for(let i= 0; i < taglist.length; i++) {
             if(obj['tagId'] === control.value) {
                 retun { tagIdExists: true };
             }
          }
          return null;
        };
      }
    

    这就是你打印错误的方式

    <mat-error *ngIf="form.get('tagId').hasError('tagIdRange')">Range</mat-error>
    

    【讨论】:

    • 我在表单中添加了您的解决方案,但收到错误 > 错误类型错误:无法读取 Object.eval [as updateDirectives] 处未定义的属性“get”错误指向输入行。感谢您的帮助。
    • 在您的模板中不要忘记将 [formGroup]="transponderForm" 添加到您的表单标签中,这就是为什么您得到 undefined 的原因还 import 和 add import {ReactiveFormsModule} from '@angular/forms' ;到你的模块
    猜你喜欢
    • 2022-06-10
    • 2020-02-20
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 2021-08-30
    • 1970-01-01
    • 1970-01-01
    • 2019-03-23
    相关资源
    最近更新 更多