【问题标题】:Angular 6 Reactive Form, FormArray Async Validator unable to highlight a FormControlAngular 6 Reactive Form,FormArray Async Validator 无法突出显示 FormControl
【发布时间】:2019-03-13 15:58:21
【问题描述】:

我在一个 FormGroup 中有一个 FormArray,每个 FormArray 都有多个 FormGroup,可以动态添加它们。

我有一个异步验证器,它需要 FormGroup 中的所有数据来验证最低 payRate,目前有一个虚拟异步验证器,它不使用所有 FormGroup 值,但需要它们来进行 API 调用。

问题来了,因为如果我想要 FormGroup 的所有数据,我需要将 Async Validator 添加到 FormGroup 而不是单个 FormControl,我需要将 ng-invalid 添加到有一个边框颜色:红色。

StqackBlitz 链接:https://stackblitz.com/edit/angular-vr4cya-b3r3od

addPay.push(
    new FormGroup({
      "payRate": new FormControl(assign.jobRate, Validators.required),
      "position": new FormControl(assign.position, Validators.required),
      "location": new FormControl(assign.location, Validators.required),
      "department": new FormControl(assign.department, Validators.required)
    },null,this.payRateValidator.bind(this))
  );

payRateValidator:

payRateValidator(control: AbstractControl): {[key: string]: any} {
const payRate = control.get('payRate').value;
  const location = control.get('location').value;
  const department = control.get('department').value;

const promise = new Promise<any>((resolve, reject) => {
  setTimeout(() => {
    if (payRate <= 13) {
      resolve({'payRateisLess': true});
    } else {
      resolve(null);
    }
  }, 1500);
});
return promise;

}

无法为 PayRate FormControl 设置异步验证器,因为异步验证器函数无法访问 FormGroup 中其他 FormControl 的值。

addPay.push(
    new FormGroup({
      "payRate": new FormControl(assign.jobRate, Validators.required, this.payRateValidator.bind(this)),
      "position": new FormControl(assign.position, Validators.required),
      "location": new FormControl(assign.location, Validators.required),
      "department": new FormControl(assign.department, Validators.required)
    })
  );

目前,当我点击 +Additional Assignment 按钮时,默认情况下,我会收到错误文本,“请输入工资率 >13”,但是当我输入值时,这并没有隐藏大于 13,因为我需要在 FormGroup 中输入所有输入,因为我有其他验证器是必需的。

在当前 FormGroup 中输入所有输入后,错误消息消失。

有没有办法只显示错误消息,仅在为整个 FormGroup 使用 Async Validator 时显示 Pay Rate Input 标签?。

【问题讨论】:

  • stackblitz 示例不是反应形式。如果您提供payRateValidator 代码,我可以提供答案
  • 这里的一般方法应该是使用工厂方法,该方法在闭包中捕获FormGroup,并为您通常传入的支付率创建一个验证器函数。
  • @AvinKavish,我更新了 Stackblitz 链接并添加了 payRateValidator。你能告诉我吗。谢谢

标签: angular angular5 angular6 angular-reactive-forms angular-forms


【解决方案1】:

您要解决的问题不是由AsyncValidator 引起的。 AsyncValidator 将导致整个表单被标记为无效,无论它放在哪里,因为支付率无效意味着 formGroup 和它所在的表单也是无效的。

要抑制您可以使用的无效组件周围的边框,

.cancel-border {
  border: none !important;
}

并将其应用于您希望没有无效边框的任何组件。如果可以编辑该代码,或者完全删除该位:

div.ng-invalid {
  border: 1px solid red;
}

话虽如此,我还使用工厂方法将您的 AsyncValidator 函数移到 payRate 控件中:

makeValidator(fg: FormGroup) {
return (control: AbstractControl) => {
  const payRate = fg.get('payRate').value;
  const location = fg.get('location').value;
  const department = fg.get('department').value;

  const promise = new Promise<any>((resolve, reject) => {
    setTimeout(() => {
      if (payRate <= 13) {
        resolve({ 'payRateisLess': true });
      } else {
        resolve(null);
      }
    }, 1500);
  });
  return promise;
}
}

并改变了评估有效性的方式。

<span [hidden]="assign.get('payRate').valid" ...>

在第 54 行和第 70 行有一些代码重复,应该查看,每次更改值时都会出现验证消息,然后消失。我认为这可以通过使用 observable 而不是 Promise 来解决。

【讨论】:

  • 嘿 Avin,我如何调用异步验证器?因为当我试图像你说的那样打电话时,我遇到了错误。请告诉我。这是更新的 stackblitz,stackblitz.com/edit/angular-vr4cya-b3r3od。您能否使用有效的异步验证器更新代码。
  • @Varun 我编辑了您发布的原始版本,并进行了所有更改,这是怎么回事?除了添加该方法之外,还有很多重构工作要做​​。
  • 因为它不是公开的,所以我看不到您所做的更改,您需要分叉然后进行更改。否则我猜他们会迷路。你能再做一次吗?我被困在这里了。
  • @Varun 应该是 good to go
  • 如果您希望验证器对整个 formGroup 的更改做出反应,而不仅仅是像以前那样只对 payRate 做出反应,您必须将验证器放回表单组中。
猜你喜欢
  • 1970-01-01
  • 2022-11-22
  • 2018-06-10
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-04
相关资源
最近更新 更多