我有一个表单,我输入电子邮件并确认电子邮件,然后继续下一页,一切顺利。当页面最初加载并且它是用户的第一次时,验证工作正常,因此输入字段不会从cookie数据预先填充。但是,当用户返回时,输入字段数据是从cookie数据预先填充的,这很好,但即使预填充文本是有效格式,仍然会禁用提交按钮。我检查了元素,似乎认为该字段是无效的,即使它是有效的格式。
我注意到当我去其中一个字段并退格以删除最后一个字符并重新插入与之前相同的字符以用于电子邮件并对下一个字段执行相同操作时,表单再次有效。尽管如此,它与以前的文本相同。
我想知道为什么在表单首次加载预填充数据时验证失败了?
这是我的代码:
export class EmailComponent implements OnInit {
public user : User;
Form : FormGroup;
displayErrors : boolean;
ngOnInit() {
// initialize model here
this.user = {
Email: '',
confirmEmail: ''
}
}
constructor(fb: FormBuilder, private cookieService: CookieService, private cryptoService: CryptoService) {
var encryptedEmail = this.cookieService.get(AppCookie.EmailAddress);
var Cookie = null;
if(encryptedEmail != null && encryptedEmail != 'undefined')
Cookie = this.cryptoService.Decrypt(encryptedEmail);
if(Cookie == null) {
this.Form = fb.group({
email: ['', [Validators.required, Validators.pattern(EMAIL_REGEXP)]],
confirmEmail: ['', [Validators.required, Validators.pattern(EMAIL_REGEXP)]]
},
{
validator: this.matchingEmailsValidator('email', 'confirmEmail')
});
}
else {
this.Form = fb.group({
email: [Cookie, [Validators.required, Validators.pattern(EMAIL_REGEXP)]],
confirmEmail: [Cookie, [Validators.required, Validators.pattern(EMAIL_REGEXP)]]
},
{
validator: this.matchingEmailsValidator('email', 'confirmEmail')
});
}
}
save(model: User, isValid: boolean)
{
model.Email = this.Form.get('email').value;
var encrypted = this.cryptoService.Encrypt(model.Email);
this.cookieService.put(AppCookie.EmailAddress, encrypted);
}
matchingEmailsValidator(emailKey: string, confirmEmailKey: string): ValidatorFn {
return (group: FormGroup): {[key: string]: any} => {
let email = group.controls[emailKey];
let confirmEmail = group.controls[confirmEmailKey];
if (email.value !== confirmEmail.value) {
return {
mismatch: true
};
}
};
}
}
以及我的观点:
<form [formGroup]="Form" novalidate (ngSubmit)="Form.valid && save(Form.value, Form.valid)">
<div class="login-wrapper">
<div class="login-page">
<section class="login-form form-group">
<p>
<input id="email"
[class.email-address-entry]="!displayErrors"
[class.email-address-entry-text]="!displayErrors && this.Form.get('email').value !='' "
type="email"
placeholder="name@domain.com" formControlName="email" />
</p>
<p class="login-form__msg">Reenter your email to confirm</p>
<input id="reenteremail"
[class.email-address-entry]="!displayErrors"
[class.entry-border-invalid]="displayErrors && !Form.valid && Form.errors?.mismatch"
[class.email-address-entry-text]="!displayErrors && this.Form.get('email').value !='' "
(blur)="displayErrors=true"
type="email" placeholder="name@domain.com"
formControlName="confirmEmail"/>
<p class="error-msg" *ngIf="displayErrors && !Form.valid && Form.errors?.mismatch">The email you entered does not match.</p>
</section>
<p class="login-confirm">
<span>
<button type="submit" [disabled]="!Form.valid" (click)="Form.get('email').length > 0 ? save(Form.value, Form.valid) : NaN">Confirm</button>
</span>
</p>
</div>
</div>
</form>
编辑:它也与此问题类似:
Angular 2 - Form is invalid when browser autofill
我尝试添加这个:
ngAfterViewChecked() {
if (Cookie) {
// enable to button here.
var element = <HTMLInputElement> document.getElementById("confirmBtn");
element.disabled = false;
}
但它不会起作用,因为字段仍然无效。我需要一种方法来手动设置重新验证或将ng-invalid更改为ng-valid。
答案 0 :(得分:1)
如果您保留对表单实例的引用(通过使用反应式表单或使用@ViewChild访问它),您应该能够在ngAfterViewInit()中编写以下内容:
for (var i in this.form.controls) {
this.form.controls[i].updateValueAndValidity();
}
或者将字段标记为触摸将在您的情况下更好:
for (var i in this.form.controls) {
this.form.controls[i].markAsTouched();
}