如果你看一下代码,你已经声明了myForm: FormGroup
,但你没有用一个值初始化它,所以初始值将是undefined
,所以验证器函数试图访问一个未定义的属性,并抛出错误,我们可以只使用?.
,它是类型脚本安全判断,它将执行自动空判断,并防止这类错误.
片段
countFieldValidator(control: FormControl) {
const fieldsArray = this.myForm?.get('fieldsArray') as FormArray; // <- changed here!
const totalCount = fieldsArray?.controls // <- changed here!
.map((fieldGroup) => fieldGroup.get('count')?.value) // <- changed here!
.reduce((sum, count) => sum + (count || 0), 0);
if (totalCount > this.availableCount) {
return { countExceeded: true };
}
return null;
}
safe check example in playground
ts
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import {
FormBuilder,
FormGroup,
Validators,
FormControl,
FormArray,
} from '@angular/forms';
@Component({
selector: 'app-forms',
templateUrl: './forms.component.HTML',
styleUrls: ['./forms.component.scss'],
encapsulation: ViewEncapsulation.None,
})
export class FormsComponent {
myForm: FormGroup;
availableCount = 100; // Set the available count limit here
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
fieldsArray: this.fb.array([this.createFieldGroup()]),
});
}
createFieldGroup(): FormGroup {
const newFieldGroup = this.fb.group({
count: [
null,
[
Validators.required,
Validators.min(1),
this.countFieldValidator.bind(this),
],
],
group: [null, Validators.required],
});
return newFieldGroup;
}
get fieldsArray() {
return this.myForm.get('fieldsArray') as FormArray;
}
countFieldValidator(control: FormControl) {
const fieldsArray = this.myForm?.get('fieldsArray') as FormArray;
const totalCount = fieldsArray?.controls
.map((fieldGroup) => fieldGroup.get('count')?.value)
.reduce((sum, count) => sum + (count || 0), 0);
if (totalCount > this.availableCount) {
return { countExceeded: true };
}
return null;
}
addFields(): void {
this.fieldsArray.push(this.createFieldGroup());
}
removeFields(index: number) {
this.fieldsArray.removeAt(index);
}
}
HTML
<form [formGroup]="myForm" class="form-container">
<div formArrayName="fieldsArray" class="form-group-container">
<div
*ngFor="let fieldGroup of fieldsArray.controls; let i = index"
[formGroupName]="i"
class="form-group"
>
<mat-form-field class="count-field">
<mat-label>Count</mat-label>
<input formControlName="count" type="number" matInput />
<mat-error *ngIf="fieldGroup?.controls?.count?.errors?.required">
Field is mandatory
</mat-error>
<mat-error
*ngIf="
!fieldGroup?.controls?.count?.errors?.required &&
fieldGroup?.controls?.count?.errors?.countExceeded
"
>
Sum of inputs exceeds 100, kindly reduce the value(s)
</mat-error>
</mat-form-field>
<button class="remove-button" (click)="removeFields(i)">delete</button>
</div>
</div>
<button type="button" label="Add" (click)="addFields()">Add</button>
</form>
Stackblitz Demo