比较 Angular 中反应形式的数量

Comparing Amount in Reactive Forms in Angular

我需要比较 amountapplied_amount。但是,它们位于不同的控件上,但它们位于同一表单组中。我应该如何检查 "amount" 是否大于 "applied_amount"?这是下面的代码。

 this.reportForm = this.fb.group({
                employee_id: [null, Validators.required],
                outlet_id: [null, Validators.required],
                grand_total: new FormControl({value: null, disabled: true}, Validators.required),
                rows: this.fb.array([]),
                applied_amount: [null, Validators.required],
            });


initGroup() {
        let rows = this.reportForm.get('rows') as FormArray;
        rows.push(this.fb.group({
            expense_account: ['', Validators.required],
            description: ['', Validators.required],
            amount: ['', Validators.required],
        },{validator: this.customValidator(rows)}))
    }



customValidator(group: any) {
        if ((group.controls.amount.value > group.parent.parent.controls.applied_amount.value)) {
            return { out1: true }
        }
        return null;
    }

您的代码存在问题,您将 FormArray(行)传递给验证器而不是组。

我建议这样重写:

initGroup() {
   let rows = this.reportForm.get('rows') as FormArray;
   rows.push(this.fb.group({
       expense_account: ['', Validators.required],
       description: ['', Validators.required],
       amount: ['', Validators.required],
   },{validator: this.customValidator})) // it will automatically be applied to the group
}

首先你不应该调用@Boris Lobanov

提到的方法customValidator方法

It says it cannot read parent of undefined

那是因为当 angular 通过 FormBuilder::group 创建 FormGroup 时,它也会调用验证器,但当前组还没有父级。只有在 FormArray::push.

之后才会设置父级

所以解决方案可能如下所示:

validator: this.customValidator
...

customValidator(group: any) {
  if (!group.parent ) {
      return;
  }
  ...

applied_amount 发生变化时,我也会对所有行触发验证。

html

<input type="number" formControlName="applied_amount" (ngModelChange)="validateAllRows()">

ts

validateAllRows() {
  const rows = this.reportForm.get('rows') as FormArray;

  rows.controls.forEach(group => {
    group.updateValueAndValidity();
  })
}

Ng-run Example

另一个方案和你的几乎一样:

validator: this.customValidator.bind(rows)
...

customValidator(this: FormArray, group: any) {
  if (group.controls.amount.value > this.parent.controls['applied_amount'].value) {
    return { out1: true }
  }
  return null;
}

这里我使用 Function.prototype.bind 方法将 FormArray 直接传递给您的验证器。

您可以添加自定义验证器。此处演示---> validator demo

 form: FormGroup;
  constructor(private formBuilder: FormBuilder) {
    this.form = this.formBuilder.group(
      {
        high: [null, Validators.required],
        low: [null, Validators.required]
      },
      {
        validator: LowHighValidation
      }
    );
  }


const LowHighValidation: ValidatorFn = (formGroup: FormGroup) => {
  console.log(formGroup);
  const low = formGroup.get("low").value;
  const high = formGroup.get("high").value;
  let validation = null;
  if (low !== null && high !== null && low < high) {
    validation = {
      validation: true
    };
  }
  return validation;
};