У меня есть поле пароля, а также поле подтверждения пароля, и все работает нормально, если вы заполняете форму сверху вниз. Однако, если я введу пароль / подтверждение пароля и затем вернусь, чтобы изменить поле пароля, поле подтверждения останется «действительным», если я не изменю его снова, чтобы пользовательский валидатор снова «проверял, совпадают ли пароли».
form.component.ts - форма получает, так сказать, свой «макет» из register.component.ts. Это позволяет мне динамически создавать формы.
import { Component, OnInit, Input } from '@angular/core';
import { FormGroup, FormControl, AbstractControl } from '@angular/forms';
import { Router } from '@angular/router';
import { ApiService } from 'src/app/services/api.service';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.scss']
})
export class FormComponent implements OnInit {
// Variable Declarations
@Input() form: {
api: string
title: string,
inputs: [{ placeholder: string, type: string, name: string, validators: []}],
link: { text: string, url: string },
button: string
};
formGroup: FormGroup;
// Variable Initialization
inputControls = {};
message = {};
// Constructor
constructor(private api: ApiService, private router: Router) { }
// On Component Init
ngOnInit() {
// Build form
this.form.inputs.forEach(input => {
if (input.name === 'confirm') {
this.inputControls[input.name] = new FormControl(null, [this.PasswordsMatch]);
} else {
this.inputControls[input.name] = new FormControl(null, input.validators);
}
});
this.formGroup = new FormGroup(this.inputControls);
}
PasswordsMatch = (control: AbstractControl): {[key: string]: boolean} | null => {
// Check if root exists first - otherwise console error ".value of undefined"
if (control.root.get('password')) {
return control.value === control.root.get('password').value ? null : {mismatch: true};
}
}
}
form.component.html
<div class="container">
<form [formGroup]="formGroup">
<span>{{ form.title }}</span>
<div *ngFor = "let input of form.inputs; let i = index">
<input [type] = "input.type"
[placeholder] = "input.placeholder"
[formControlName] = "input.name">
</div>
<button [disabled]="!formGroup.valid">{{ form.button }}</button>
<a [routerLink]="form.link.url">{{ form.link.text }}</a>
</form>
</div>
register.component.ts -Я не мог понять, как передать пользовательский валидатор для поля подтверждения пароля, поэтому я просто передал Validators.required, но он просто перезаписывается пользовательским валидатором при создании формы.
import { Component } from '@angular/core';
import { Validators } from '@angular/forms';
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.scss']
})
export class RegisterComponent {
// Validators (Validators.required is used to differentiate between error messages)
validators = {
name: [ Validators.required, Validators.pattern('[a-zA-Z]{2,20}') ],
email: [ Validators.required, Validators.pattern('[a-zA-Z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}')],
username: [ Validators.required, Validators.pattern('[a-zA-Z0-9.+%+-]{1,30}')],
password: [ Validators.required, Validators.pattern('(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9!@#$%^&*-_=+]{10,}')],
confirm: [ Validators.required, ]
};
// Form data
form = {
api: 'register',
title: 'Are you ready?',
inputs: [
{ placeholder: 'First Name', type: 'text', name: 'name', validators: this.validators.name },
{ placeholder: 'Email Address', type: 'email', name: 'email', validators: this.validators.email },
{ placeholder: 'Mage Name', type: 'text', name: 'username', validators: this.validators.username },
{ placeholder: 'Password', type: 'password', name: 'password', validators: this.validators.password },
{ placeholder: 'Confirm Password', type: 'password', name: 'confirm', validators: this.validators.confirm },
],
link: { text: 'I\'m already a Wizard!', url: '/login' },
button: 'I\'m Ready for War'
};
constructor() {}
}
Спасибозаранее за вашу помощь.