比较 Angular 中反应形式的数量
Comparing Amount in Reactive Forms in Angular
我需要比较 amount
和 applied_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();
})
}
另一个方案和你的几乎一样:
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;
};
我需要比较 amount
和 applied_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();
})
}
另一个方案和你的几乎一样:
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;
};