使用 Angular Reactive Forms 验证年龄是否超过 18 岁
Validate if age is over 18 years old with Angular Reactive Forms
有没有办法在用户使用 Angular 验证器输入出生日期时检查他们是否超过 18 岁?
我的表单如下所示:
<form [formGroup]="authForm" (ngSubmit)="submitForm()">
<label>Date of birth</label>
<input formControlName="day" maxlength="2" placeholder="DD" type="text" />
<input formControlName="month" maxlength="2" placeholder="MM" type="text" />
<input formControlName="year" maxlength="4" placeholder="YYYY" type="text" />
<button [disabled]="!authForm.valid" type="submit"> Check age </button>
</form>
然后我在 TS 文件中设置了这些验证器:
if (this.authType === 'register') {
this.authForm.addControl('year', new FormControl('', [Validators.required, Validators.maxLength(4), Validators.minLength(4)]));
this.authForm.addControl('month', new FormControl('', [Validators.required, Validators.maxLength(2)]));
this.authForm.addControl('day', new FormControl('', [Validators.required, Validators.maxLength(2)]));
}
因此,如果在验证器中满足上述条件,则该按钮将启用。但我还需要在启用之前检查输入的日期是否超过 18 岁。这似乎很棘手,因为日期是通过 3 个输入(dd、mm、yyyy)输入的。在这种情况下,我无法使用输入日期标签。任何建议或意见表示赞赏。谢谢!
P.S。感谢您提供有关使用 MomentJS 的所有建议。我已经在应用程序的其他地方使用它,所以我也会在这里使用它。
不,您必须制作自定义验证器。这个验证器也必须放置在整个 FormGroup 上,而不是仅仅放在一个 FormControl 上,因为只要 3 个输入值中的任何一个发生变化,验证就需要 运行。
你如何实现验证取决于你,因为这涉及到日期,但我总是使用 momentjs 来处理日期。
在这种情况下,您需要配置一个将挂接到完整 FormGroup
的自定义验证器。
基于 momentjs 的方法如下所示:
export function minimumAge(age:number): ValidatorFn {
return (fg: FormGroup): ValidationErrors => {
let result: ValidationErrors = null;
if (fg.get('year').valid && fg.get('month').valid && fg.get('day').valid) {
// carefull, moment months range is from 0 to 11
const value: { year: string, month: string, day: string } = fg.value;
const date = moment({ year: +value.year, month: (+value.month) - 1, day: +value.day }).startOf('day');
if (date.isValid()) {
// https://momentjs.com/docs/#/displaying/difference/
const now = moment().startOf('day');
const yearsDiff = date.diff(now, 'years');
if (yearsDiff > -age) {
result = {
'minimumAge': {
'requiredAge': age,
'actualAge': yearsDiff
}
};
}
}
}
return result;
};
}
export class DateEditComponent {
readonly authForm: FormGroup;
constructor(private _fb: FormBuilder) {
this.authForm = this._fb.group({
year: ['', [Validators.required, Validators.maxLength(4), Validators.minLength(4)]],
month: ['', [Validators.required, Validators.maxLength(2)]],
day: ['', [Validators.required, Validators.maxLength(2)]]
});
this.authForm.setValidators(minimumAge(18));
}
}
有关实际示例,请查看 here
请注意,在这种情况下,我不会对单个输入字段进行任何 format/range 验证。
有没有办法在用户使用 Angular 验证器输入出生日期时检查他们是否超过 18 岁?
我的表单如下所示:
<form [formGroup]="authForm" (ngSubmit)="submitForm()">
<label>Date of birth</label>
<input formControlName="day" maxlength="2" placeholder="DD" type="text" />
<input formControlName="month" maxlength="2" placeholder="MM" type="text" />
<input formControlName="year" maxlength="4" placeholder="YYYY" type="text" />
<button [disabled]="!authForm.valid" type="submit"> Check age </button>
</form>
然后我在 TS 文件中设置了这些验证器:
if (this.authType === 'register') {
this.authForm.addControl('year', new FormControl('', [Validators.required, Validators.maxLength(4), Validators.minLength(4)]));
this.authForm.addControl('month', new FormControl('', [Validators.required, Validators.maxLength(2)]));
this.authForm.addControl('day', new FormControl('', [Validators.required, Validators.maxLength(2)]));
}
因此,如果在验证器中满足上述条件,则该按钮将启用。但我还需要在启用之前检查输入的日期是否超过 18 岁。这似乎很棘手,因为日期是通过 3 个输入(dd、mm、yyyy)输入的。在这种情况下,我无法使用输入日期标签。任何建议或意见表示赞赏。谢谢!
P.S。感谢您提供有关使用 MomentJS 的所有建议。我已经在应用程序的其他地方使用它,所以我也会在这里使用它。
不,您必须制作自定义验证器。这个验证器也必须放置在整个 FormGroup 上,而不是仅仅放在一个 FormControl 上,因为只要 3 个输入值中的任何一个发生变化,验证就需要 运行。
你如何实现验证取决于你,因为这涉及到日期,但我总是使用 momentjs 来处理日期。
在这种情况下,您需要配置一个将挂接到完整 FormGroup
的自定义验证器。
基于 momentjs 的方法如下所示:
export function minimumAge(age:number): ValidatorFn {
return (fg: FormGroup): ValidationErrors => {
let result: ValidationErrors = null;
if (fg.get('year').valid && fg.get('month').valid && fg.get('day').valid) {
// carefull, moment months range is from 0 to 11
const value: { year: string, month: string, day: string } = fg.value;
const date = moment({ year: +value.year, month: (+value.month) - 1, day: +value.day }).startOf('day');
if (date.isValid()) {
// https://momentjs.com/docs/#/displaying/difference/
const now = moment().startOf('day');
const yearsDiff = date.diff(now, 'years');
if (yearsDiff > -age) {
result = {
'minimumAge': {
'requiredAge': age,
'actualAge': yearsDiff
}
};
}
}
}
return result;
};
}
export class DateEditComponent {
readonly authForm: FormGroup;
constructor(private _fb: FormBuilder) {
this.authForm = this._fb.group({
year: ['', [Validators.required, Validators.maxLength(4), Validators.minLength(4)]],
month: ['', [Validators.required, Validators.maxLength(2)]],
day: ['', [Validators.required, Validators.maxLength(2)]]
});
this.authForm.setValidators(minimumAge(18));
}
}
有关实际示例,请查看 here
请注意,在这种情况下,我不会对单个输入字段进行任何 format/range 验证。