angular - 比较 2 个输入字段的值以通过模板验证 Angular 7 中的表单

标签 angular typescript angular-validation

我在迁移到 Angular 7 的第一周,我一直在使用基于模板的基本验证在我的项目中制作基本表单,但我现在需要验证表单,因为一个字段的值必须是高于其他

我已经尝试在组件 Controller 中使用这些值本身,但是虽然我能够确认这些值是否有效,但我无法使用此代码向用户显示问题所在

if (issueThresholdForm.value.lowScore > issueThresholdForm.value.highScore) {
  // Show user error
  // This is the messing part, I guess
}

这是我正在使用的模板

<div *ngIf="_issueCategory">
  <form (submit)="submitIssueThreshold(issueThresholdForm)" #issueThresholdForm="ngForm">
    <mat-form-field class="half-width" floatLabel="always">
      <mat-label [translate]="'issueThreshold.modals.highScore'"></mat-label>
      <input name="highScore" type="number" matInput placeholder="0" [(ngModel)]="_issueCategory.highScore"
        required #highScore="ngModel">
    </mat-form-field>
    <mat-form-field class="half-width" floatLabel="always">
      <mat-label [translate]="'issueThreshold.modals.lowScore'"></mat-label>
      <input name="lowScore" type="number" matInput placeholder="0" [(ngModel)]="_issueCategory.lowScore"
        required #lowScore="ngModel">
    </mat-form-field>
    <mat-form-field class="full-width" floatLabel="always">
      <mat-label [translate]="'issueThreshold.modals.description'"></mat-label>
      <textarea name="description" matInput [(ngModel)]="_issueCategory.thresholdDescription">
            </textarea>
    </mat-form-field>
    <div class="modal-footer">
      <button type="button" class="btn btn-secondary" data-dismiss="modal" [translate]="'modal-confirm.cancel'"></button>
      <button type="submit" class="btn btn-primary primary" [disabled]="issueThresholdForm.invalid || issueThresholdForm.pristine" [translate]="'modal-confirm.submit'"></button>
    </div>
  </form>
</div>

最佳答案

编辑:

以 react 方式使用相同的解决方案进行编辑。因此,创建表单组并添加附加到表单组的自定义验证器:

_issueCategory = { lowScore: 1, highScore: 2 };

issueThresholdForm: FormGroup;

constructor(private fb: FormBuilder) {
  this.issueThresholdForm = this.fb.group({
    highScore: [this._issueCategory.highScore, [Validators.required]],
    lowScore: [this._issueCategory.lowScore, [Validators.required]]
  }, { validators: validateScore })
}

验证器函数:

export function validateScore(
  control: AbstractControl
): ValidationErrors | null {
  if (control && control.get("highScore") && control.get("lowScore")) {
    const highscore = control.get("highScore").value;
    const lowscore = control.get("lowScore").value;  
    return (lowscore > highscore) ? { scoreError: true } : null
  }
  return null;
}

然后你可以删除 ngModel(重要!),因为它们不应该与 react 形式混合。您还可以删除表单的所有验证,例如 required,因此最终输入看起来很简单:

<input type="number" matInput placeholder="0" formControlName="lowScore">

STACKBLITZ


原创:

强烈,强烈建议 Reactive forms ,一开始他们可能会感到困惑,但完全值得。您可以更好地控制表单,并且正如 Nithin Kumar Biliya 在评论中提到的那样,单元测试更容易。

话虽这么说....

这是一个使用模板驱动表单的解决方案,因为这正是您当前正在使用的。

你可以创建一个附加到表单标签的指令,在该指令中有一个验证器来比较 highscore 和 lowscore 的值并将错误附加到表单,或者返回 null (这在表格中被认为是有效的)。所以验证器看起来像这样:

import { Directive } from "@angular/core";
import {
  AbstractControl,
  NG_VALIDATORS,
  Validator,
  ValidationErrors
} from "@angular/forms";

@Directive({
  selector: "[scoreValidation]",
  providers: [
    {
      provide: NG_VALIDATORS,
      useExisting: ScoreValidatorDirective,
      multi: true
    }
  ]
})
export class ScoreValidatorDirective implements Validator {
  constructor() {}

  // here control is the formgroup
  validate(control: AbstractControl): ValidationErrors | null {
    if (control && control.get("highScore") && control.get("lowScore")) {

      // the form controls and their value
      const highscore = control.get("highScore").value;
      const lowscore = control.get("lowScore").value;

      // not valid, return an error
      if (lowscore > highscore) {
        return { scoreError: true };
      }
      // valid
      return null;
    }
    // form controls do not exist yet, return null
    return null;
  }
}

将指令添加到您的应用程序模块中的声明数组,并通过将此指令附加到表单标签来使用它:

<form .... scoreValidation>

错误可以使用 *ngIf="issueThresholdForm.hasError('scoreError')

显示

STACKBLITZ

关于angular - 比较 2 个输入字段的值以通过模板验证 Angular 7 中的表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58155812/

相关文章:

angular - 在Ionic2中导入trackingjs作为第三方库

javascript - 期望验证器返回 Promise 或 Observable

javascript - 如何验证具有一个输入字段的 Angular 2 中的表单?

angular - 无法解析 MatDialogRef angular 4 的所有参数

本地存储的 Angular 异步问题

javascript - ng2 [已禁用] ="!myInput.value"无法正常工作

javascript - 单击父按钮单击时如何重置子输入的数据和 View ?

javascript - Angular electron mysql create connection 不是一个函数

TypeScript - 从 DefinelyTyped 导入一些使用声明文件(类型)的 npm 包时出现问题

javascript - 如何在 Angular 中为自定义验证器添加自定义验证错误消息