我知道这个问题已被其他时间以类似的形式提出,但我的情况有所不同;让我解释一下:
我有一个重置密码表单,有3个字段(旧密码,新密码,确认密码)。当然,我需要检查提交的passowrd是否与提交的确认密码相同,我想在点击提交之前执行此操作。我将表单定义如下(在component.ts中)
this.form = fb.group({
// define your control in you form
oldpassword: ['', Validators.required],
password: ['', [Validators.required, Validators.minLength(4), Validators.maxLength(10)]],
confirmPassword: ['', [Validators.required, Validators.minLength(4), Validators.maxLength(10)]]
}, {
validator: PasswordValidation.MatchPassword // your validation method
});
export class PasswordValidation {
static MatchPassword(AC: AbstractControl) {
const password = AC.get('password').value; // to get value in input tag
const confirmPassword = AC.get('confirmPassword').value; // to get value in input tag
if (password !== confirmPassword) {
AC.get('confirmPassword').setErrors({MatchPassword: true})
} else {
return null
}
}
}
问题是,如果在编译“新密码”之前更改“确认密码字段”,则表单无效。换句话说,如果我尊重字段的垂直o9rder,一切都没问题,但如果我按不同的顺序编译字段,那么表单仍然无效。
这里是html代码:(正如你所看到的,它有点令人困惑,因为我有其他UX约束,这对应于用户可能的交互)
<form [formGroup]="form" novalidate (ngSubmit)="modal.open()">
<div class="form-group">
<label for="oldpassword">Inserisci vecchia password</label>
<input type="password" id="oldpassword" class="form-control" formControlName="oldpassword">
<div
*ngIf="form.controls['oldpassword'].hasError('required') && form.controls['oldpassword'].touched"
class="alert alert-danger">
Campo obbligatorio
</div>
</div>
<div class="form-group">
<label for="password">Inserisci nuova password</label>
<input type="password" id="password" class="form-control" formControlName="password">
<div *ngIf="form.controls['password'].hasError('required') && form.controls['password'].touched"
class="alert alert-danger">
Campo obbligatorio
</div>
<div *ngIf="form.controls['password'].hasError('minlength') && form.controls['password'].touched"
class="alert alert-danger">
Lunghezza minima: 4 caratteri.
</div>
</div>
<div class="form-group">
<label for="confirmPassword">Ripeti nuova password</label>
<input type="password" class="form-control" id="confirmPassword" formControlName="confirmPassword">
<div class="alert alert-danger"
*ngIf="form.errors?.MatchPassword || (form.controls['confirmPassword'].hasError('required') && form.controls['confirmPassword'].touched)">
Le password non corrispondono
</div>
</div>
<div *ngIf="!this.state.controlloIn; else elseBlock">
<button type="submit" class="btn btn-primary btn-update" [disabled]="!form.valid || this.controlloInvia">
Invia Richiesta
</button>
</div>
<ng-template #elseBlock>
<button type="submit" class="btn btn-primary btn-update" [disabled]="true">
Invia Richiesta
</button>
</ng-template>
</form>
我不是一个有角度的专家,所以如果你能提出我其他最好的练习,我会非常高兴。感谢所有
答案 0 :(得分:2)
this.profileForm = this.formBuilder.group({
password: [this.profile.password, [
Validators.required,
Validators.minLength(4)]
],
passwordCheck: [this.profile.password, [
Validators.required,
Validators.minLength(4)
]],
oldPassword: [this.profile.oldPassword, [
Validators.required]],
}, { validator: matchingPasswordsValidator('password', 'passwordCheck') });
这是我用于更改密码的表单。 它使用单独的验证器,该验证器不验证它验证整个表单的字段。
export function matchingPasswordsValidator(passwordKey: string, confirmPasswordKey: string) {
return (group: FormGroup): { [key: string]: any } => {
let password = group.controls[passwordKey];
let confirmPassword = group.controls[confirmPasswordKey];
if (password.value !== confirmPassword.value) {
return {
mismatchedPasswords: true
};
}
}
}
@Directive({
selector: '[appMatchingPasswordsValidator]',
providers: [{
provide: NG_VALIDATORS, useExisting: MatchingPasswordsValidatorDirective, multi: true
}]
})
export class MatchingPasswordsValidatorDirective {
constructor() { }
validate(c: AbstractControl) {
matchingPasswordsValidator("test", "test");
}
}
然后这是用于匹配密码的指令。或者您在表格中提供的任何2把钥匙。
答案 1 :(得分:2)
您正在确认字段上直接设置错误。如果您不再触摸该字段,则会在其上设置错误,并且永远不会被删除。仅当字段已被编辑时才对角色运行验证器,因为您可以合理地认为如果某个字段被标记为错误并且尚未编辑,则它仍处于错误状态。
我建议您将此错误直接放在FormGroup
上:
static MatchPassword(AC: AbstractControl) {
const password = AC.get('password').value; // to get value in input tag
const confirmPassword = AC.get('confirmPassword').value; // to get value in input tag
if (password !== confirmPassword) {
return {MatchPassword: true};
} else {
return null
}
}
<div class="alert alert-danger"
*ngIf="form.errors?.MatchPassword || (form.controls['confirmPassword'].hasError('required') && form.controls['confirmPassword'].touched)">
Le password non corrispondono
</div>
答案 2 :(得分:0)
我刚遇到这个问题,发现了一个不同的修复方法。当密码匹配时,我在返回null之前调用AbstractFormControl的updateValueAndValidity函数(onlySelf为true,emitEvent为false)。这使我能够对password和confirmPassword输入进行验证。我可以在密码之前输入确认的密码,并且验证状态正确显示。
static MatchPassword(AC: AbstractControl) {
const password = AC.get('password').value;
const confirmPassword = AC.get('confirmPassword').value;
if (password !== confirmPassword) {
AC.get('confirmPassword').setErrors({MatchPassword: true})
} else {
AC.get('confirmPassword').updateValueAndValidity(
{onlySelf: true, emitEvent: false}
);
return null;
}
}
答案 3 :(得分:0)
我知道这是您问题的较晚答案,但想提供一种方法。
您可以通过在.value
上调用ngModel
来比较输入的值。
您可以在下面的代码块中看到它的工作原理
<div *ngIf="newPassword.dirty || newPassword.touched">
<div class="alert alert-danger" *ngIf="newPassword.value.match(passwordCurrent.value)">
Current password and New Password can't match.
</div>
</div>
长版代码
<div class="form-group">
<div class="input-group input-group-alternative">
<div class="input-group-prepend">
<span class="input-group-text"><i
class="fa fa-unlock-alt"></i></span>
</div>
<input required minlength="6" [(ngModel)]="passwordOneIn"
#newPassword="ngModel" name="newPassword" class="form-control"
placeholder="New Password" type="password">
</div>
</div>
<!--#####check if the password and current password match########-->
<div *ngIf="newPassword.dirty || newPassword.touched">
<div class="alert alert-danger" *ngIf="newPassword.value.match(passwordCurrent.value)">
Current password and New Password can't match.
</div>
</div>
<div *ngIf="newPassword.invalid && (newPassword.dirty || newPassword.touched)"
class="alert alert-danger">
<div *ngIf="newPassword.errors.required">
password is required.
</div>
</div>
<div class="form-group">
<div class="input-group input-group-alternative">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-unlock-alt"></i></span>
</div>
<input required minlength="6" [(ngModel)]="passwordTwoIn"
#retypedPassword="ngModel" name="retypedPassword"
class="form-control" placeholder="Retype Password" type="password">
</div>
</div>
<div *ngIf="retypedPassword.invalid && (retypedPassword.dirty || retypedPassword.touched)"
class="alert alert-danger">
<div *ngIf="retypedPassword.errors.required">
password is required.
</div>
</div>
<!--##### check if the new password and retyped password match ########-->
<div *ngIf="retypedPassword.dirty || retypedPassword.touched">
<div class="alert alert-danger" *ngIf="!newPassword.value.match(retypedPassword.value)">
New password and Retyped Password don't match.
</div>
</div>
<button [disabled]="changePasswordFrom.form.invalid || newPassword.value.match(passwordCurrent.value) || !newPassword.value.match(retypedPassword.value)"
type="submit" class="btn btn-primary mt-4">Change Password</button>
</div>