Angular 6 响应式表单,FormArray 异步验证器无法突出显示 FormControl

Angular 6 Reactive Form, FormArray Async Validator unable to highlight a FormControl

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

我有一个异步验证器,它需要 FormGroup 中的所有数据来验证最低 payRate,目前有一个虚拟异步验证器,它不使用所有 FormGroup 值,但需要它们来制作 API 呼叫.

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

StqackBlitz link: 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 按钮时,默认情况下,我会收到错误文本 "Please enter Pay Rate >13",但是当我输入大于 13 的值,因为 我需要在 FormGroup 中输入所有输入,因为我有其他验证器是必需的。

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

有什么方法可以只显示错误消息,只显示整个 FormGroup 的异步验证程序时的支付率输入标签???。

您要解决的问题不是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 来解决。