Я написал свои собственные валидаторы для проверки полей ввода моей реактивной формы, но они, похоже, не работают. Первые два никогда не вызывают ошибки, а последний ломает все, как только я добавляю его в свой код. С помощью augury я отлаживал все, что мог, и обнаружил, что с моим validatePasswords он сразу же переходит к методу, в то время как я даже ничего не трогал. Если кто-нибудь из вас сможет понять, почему это происходит или почему другие мои валидаторы никогда не выдают ошибку, это было бы потрясающе!
function validateEmail(control: FormGroup): { [key: string]: any } {
var mailReg = /^([a-zA-Z]+[a-zA-Z0-9.\-_éèàùäëïöüâêîôû]*)@([a-z]+)[.]([a-z]+)([.][a-z]+)*$/g;
if (!mailReg.test(control.get('email').value)) {
return { noValidEmail: true };
}
return null;
}
function validatePhone(control: FormGroup): { [key: string]: any } {
var phoneReg = /^0{0,2}(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)\d{7,14}$/;
if (!phoneReg.test(control.get('phone').value)) {
return { noValidPhone: true };
}
return null;
}
function validatePassword(control: FormGroup): { [key: string]: any } {
if (
control.get('password').value !== control.get('passwordConfirmation').value
) {
return { noMatchingPasswords: true };
}
return null;
}
public register: FormGroup;
constructor(
public dialogRef: MatDialogRef<RegisterFormComponent>,
private fb: FormBuilder,
private http: HttpClient
) {}
ngOnInit() {
this.register = this.fb.group({
firstName: ['', [Validators.required, Validators.minLength(2)]],
lastName: ['', [Validators.required, Validators.minLength(2)]],
email: [
'',
[Validators.required, Validators.minLength(5)],
validateEmail
],
phone: [
'',
[Validators.required, Validators.minLength(8)],
validatePhone
],
country: [''],
password: ['', [Validators.required, Validators.minLength(5)]],
passwordConfirmation: [
'',
[Validators.required, Validators.minLength(5), validatePassword]
]
});
}
getErrorMessage(errors: any) {
if (errors.required) {
return 'is required';
} else if (errors.noValidEmail) {
return 'not a valid email';
} else if (errors.noValidPhone) {
return 'no valid phone number';
} else if (errors.noMatchingPasswords) {
return 'passwords don\'t match';
} else if (errors.minlength) {
return `need at least ${errors.minlength.requiredLength} characters`;
}
}
ERROR TypeError: Cannot read property 'get' of undefined
at FormGroupDirective.push../node_modules/@angular/forms/fesm5/forms.js.FormGroupDirective.addControl (forms.js:5280)
at FormControlName.push../node_modules/@angular/forms/fesm5/forms.js.FormControlName._setUpControl (forms.js:5882)
at FormControlName.push../node_modules/@angular/forms/fesm5/forms.js.FormControlName.ngOnChanges (forms.js:5803)
at checkAndUpdateDirectiveInline (core.js:22085)
at checkAndUpdateNodeInline (core.js:23353)
at checkAndUpdateNode (core.js:23315)
at debugCheckAndUpdateNode (core.js:23949)
at debugCheckDirectivesFn (core.js:23909)
at Object.eval [as updateDirectives] (RegisterFormComponent.html:5)
at Object.debugUpdateDirectives [as updateDirectives] (core.js:23901)
<h3 mat-dialog-title>Register</h3>
<mat-dialog-content>
<form [formGroup] = "register" (ngSubmit) = "onSubmit()">
<mat-form-field>
<input matInput aria-label = "First name" placeholder = "First name" type = "text" formControlName = "firstName"
class = "browser-default" required />
<mat-error *ngIf = "register.get('firstName')['errors'] && register.get('firstName').touched">
{{ getErrorMessage(register.get('firstName')['errors']) }}
</mat-error>
</mat-form-field>
<mat-form-field>
<input matInput aria-label = "Last name" placeholder = "Last name" type = "text" formControlName = "lastName"
class = "browser-default" required />
<mat-error *ngIf = "register.get('lastName')['errors'] && register.get('lastName').touched">
{{ getErrorMessage(register.get('lastName')['errors']) }}
</mat-error>
</mat-form-field>
<mat-form-field>
<input matInput aria-label = "Email" placeholder = "Email" type = "text" formControlName = "email" class = "browser-default"
required />
<mat-error *ngIf = "register.get('email')['errors'] && register.get('email').touched">
{{ getErrorMessage(register.get('email')['errors']) }}
</mat-error>
</mat-form-field>
<mat-form-field>
<input matInput aria-label = "Phone" placeholder = "Phone" type = "text" formControlName = "phone" class = "browser-default"
required />
<mat-error *ngIf = "register.get('phone')['errors'] && register.get('phone').touched">
{{ getErrorMessage(register.get('phone')['errors']) }}
</mat-error>
</mat-form-field>
<mat-form-field>
<input matInput aria-label = "Country" placeholder = "Country" type = "text" formControlName = "country"
class = "browser-default" />
</mat-form-field>
<mat-form-field>
<input matInput aria-label = "Password" placeholder = "Password" type = "password" formControlName = "password"
class = "browser-default" required />
<mat-error *ngIf = "register.get('password')['errors'] && register.get('password').touched">
{{ getErrorMessage(register.get('password')['errors']) }}
</mat-error>
</mat-form-field>
<mat-form-field>
<input matInput aria-label = "Confirmation Password" placeholder = "Confirmation Password" type = "password"
formControlName = "passwordConfirmation" class = "browser-default" required />
<mat-error *ngIf = "register.get('passwordConfirmation')['errors'] && register.get('passwordConfirmation').touched">
{{ getErrorMessage(register.get('passwordConfirmation')['errors']) }}
</mat-error>
</mat-form-field>
<div class = "buttonDiv">
<button mat-button (click) = "onNoClick()">Cancel</button>
<button mat-button type = "submit" [disabled] = "!register.valid">Register</button>
</div>
</form>
</mat-dialog-content>
эти ошибки новые, но теперь они также появляются:
ERROR Error: formGroup expects a FormGroup instance. Please pass one in.
Example:
<div [formGroup] = "myGroup">
<input formControlName = "firstName">
</div>
In your class:
this.myGroup = new FormGroup({
firstName: new FormControl()
});
at Function.push../node_modules/@angular/forms/fesm5/forms.js.ReactiveErrors.missingFormException (forms.js:1443)
at FormGroupDirective.push../node_modules/@angular/forms/fesm5/forms.js.FormGroupDirective._checkFormPresent (forms.js:5414)
at FormGroupDirective.push../node_modules/@angular/forms/fesm5/forms.js.FormGroupDirective.ngOnChanges (forms.js:5237)
at checkAndUpdateDirectiveInline (core.js:22085)
at checkAndUpdateNodeInline (core.js:23353)
at checkAndUpdateNode (core.js:23315)
at debugCheckAndUpdateNode (core.js:23949)
at debugCheckDirectivesFn (core.js:23909)
at Object.eval [as updateDirectives] (RegisterFormComponent.html:3)
at Object.debugUpdateDirectives [as updateDirectives] (core.js:23901)
а также
ERROR TypeError: Cannot read property 'value' of null
at validatePassword (register-form.component.ts:29)
at forms.js:658
at Array.map (<anonymous>)
at _executeValidators (forms.js:658)
at FormControl.validator (forms.js:623)
at FormControl.push../node_modules/@angular/forms/fesm5/forms.js.AbstractControl._runValidator (forms.js:2914)
at FormControl.push../node_modules/@angular/forms/fesm5/forms.js.AbstractControl.updateValueAndValidity (forms.js:2890)
at new FormControl (forms.js:3241)
at FormBuilder.push../node_modules/@angular/forms/fesm5/forms.js.FormBuilder.control (forms.js:6462)
at FormBuilder.push../node_modules/@angular/forms/fesm5/forms.js.FormBuilder._createControl (forms.js:6502)
(строка 29 это: control.get('password').value !== control.get('passwordConfirmation').value
)
Учитывая, что пользовательский валидатор validatePassword
включает перекрестная проверка (проверка нескольких полей — FormControls password
и passwordConfirmation
), вы должны передать этот валидатор во втором аргументе инициализации формы register
.
Вы можете оставить другие FormControls такими, какие они есть. Удалите validatePassword
из passwordConfirmation и добавьте его во второй аргумент formBuilder.
this.register = this.fb.group({
.
.
password: ['', [Validators.required, Validators.minLength(5)]],
passwordConfirmation: [
'',
[Validators.required, Validators.minLength(5)]
]
}, { validators: validatePassword });
Что касается вашей второй проблемы, это связано с тем, что register
FormGroup не определена при отображении страницы. Вы должны переместить его в свой конструктор или просто инициализировать FormControls, когда вы объявляете свойство «register» в своем классе.
constructor(
public dialogRef: MatDialogRef<RegisterFormComponent>,
private fb: FormBuilder,
private http: HttpClient
) {
this.register = fb.group({
.
.
// your FormControls
.
});
}
Или
export class YourComponent implements OnInit {
public register: FormGroup = this.fb.group({
.
.
// your FormControls
.
})
Ах, рад слышать, что эта часть работает. Хм.. Нет сообщения об ошибке, да? Вы, должно быть, имеете в виду getErrorMessage()
? Вероятно, это связано с тем, что вам может потребоваться передать свойство error
из register
FormGroup вместо свойства ошибки из каждого отдельного элемента управления FormControl. Затем в своем шаблоне вы должны сделать что-то вроде {{ getErrorMessage(register.errors) }}
. Вы понимаете, что я пытаюсь сказать? :)
Ну, это исправляет часть этого, теперь проблема в том, что он проверяет это с каждым полем (имя получает недопустимую ошибку телефона), но я думаю, что это можно исправить, поместив эту строку только для тех, у кого есть дополнительная проверка. Обновление: я сделал это, и мы снова на один шаг ближе, теперь проблема, с которой я сталкиваюсь, заключается в том, что он показывает неправильную ошибку в этих полях, все получает недопустимую ошибку электронной почты
Итак, я сделал то, что вы сказали, но это не сработало, поэтому я немного импровизировал и поместил каждый валидатор в
{ validators : [validatePassword, validatePhone, validateEmail ]}
Валидации работают, но сообщения все равно не отображаются. Почему?