2017-02-13 100 views
0

我有一個表格,我輸入一個電子郵件,確認電子郵件,然後繼續到下一個頁面,一切都很好。當頁面最初加載並且它是用戶的第一次時,驗證工作正常,所以輸入字段不會從cookie數據預填充。但是,當用戶返回時,輸入字段數據是從cookie數據預填充的,這很好,但即使預先填充的文本是有效格式,提交按鈕仍然被禁用。我檢查了這些元素,似乎認爲該字段是ng-invalid,即使它是有效的格式。當輸入字段預填充字段是無效的

我注意到,當我去的領域之一,退格爲之前刪除的最後一個字符,然後重新插入相同的字符的電子郵件,並在接下來的一個領域一樣,形式再次有效。儘管如此,它和以前一樣。

我想知道爲什麼驗證失敗時窗體第一次加載預填充數據?

這裏是我的代碼:

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="[email protected]" 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="[email protected]" 
       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

你應該也可以在那裏拋出一個TypeScript標記。 – PaulBGD

+0

@PaulBGD謝謝! – Euridice01

回答

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(); 
}