2017-12-27 1052 views
0

請幫助理解。我正在嘗試爲被動表單編寫自定義驗證器。爲什麼表單值對象爲空?

組件:

private form: FormGroup; 

    ngOnInit() { 
    const this_ = this; 

    this.form = new FormGroup({ 
     'email':  new FormControl(null, [Validators.required, Validators.email]), 
     'password': new FormControl(null, [Validators.required, Validators.minLength(6)]), 
     'password2': new FormControl(null, [Validators.required, Validators.minLength(6), this_.comparePasswords]), 
     'name':  new FormControl(null, [Validators.required]), 
     'agree':  new FormControl(false, [Validators.requiredTrue]) 
    }); 
    } 

    comparePasswords(c: FormControl) { 
    console.log(c); 

    const hashStr = Md5.hashStr(c.value.password); 
    const hashStr2 = Md5.hashStr(c.value.password2); 

    console.log(hashStr, hashStr2); 

    return (hashStr === hashStr2) ? null : { 
     comparePasswords: { 
     valid: false 
     } 
    }; 
    } 

所有你需要連接的進口。加載頁面後,瀏覽器控制檯立即顯示錶單對象,其中值對象爲空。

我無法檢查函數comparePasswords()。

控制檯顯示如下:

ERROR TypeError: Cannot read property 'password' of null

LIVE EXAMPLE HERE

+1

而是用空的默認密碼值新formcontrol的,你爲什麼不設置默認值爲空字符串'「」'?我敢打賭,這是問題。 –

+0

對不起,我沒有看到@ I.R.R回答。評論 – Wallace

回答

3

變化null""

this.form = new FormGroup({ 
    'email':  new FormControl("", [Validators.required, Validators.email]), 
    'password': new FormControl("", [Validators.required, Validators.minLength(6)]), 
    'password2': new FormControl("", [Validators.required, Validators.minLength(6), this_.comparePasswords]), 
    'name':  new FormControl("", [Validators.required]), 
    'agree':  new FormControl(false, [Validators.requiredTrue]) 
}); 
+0

您是否使用OP的測試鏈接運行此代碼並驗證它解決了問題? – smac89

+0

@ smac89是的它適用於提供的示例 – Wallace

+0

這是適用於我的。 – Niladri

0

除了提供初始值null,您是在formcontrol設置自定義驗證,所以你實際得到的自定義驗證器只是formcontrol password2,不是整個formgroup。

因此,我會將自定義驗證器放在formgroup級別,或者更好的是,爲密碼創建一個嵌套的formgroup併爲其應用驗證器。爲什麼?因爲如果您在整個表單上應用驗證器,則只要發生任何變化就會被觸發。但在這個示例中,我將它應用於整個表單並縮小了您的代碼。此外,在表單組級別上應用自定義驗證程序(嵌套或不嵌套)的優勢將兼顧檢查輸入。由於驗證者坐在你的問題中,只會在password2字段發生更改時檢查password2是否匹配password。那麼如果在修改password2後修改password字段會發生什麼情況,則不會顯示錯誤,並且窗體被視爲有效。

因此,建立形式,例如:

constructor(private fb: FormBuilder) { } 

ngOnInit() { 
    this.form = this.fb.group({ 
    password: ['', [Validators.required, Validators.minLength(6)]], 
    password2: ['', [Validators.required, Validators.minLength(6)]], 
    },{validator: this.comparePasswords}); 
} 

然後自定義驗證應該是這樣的:

comparePasswords(c: FormGroup) { 
    const hashStr = Md5.hashStr(c.controls.password.value); 
    const hashStr2 = Md5.hashStr(c.controls.password2.value); 
    return (hashStr === hashStr2) ? null : { notSame: true }; 
} 

你可以比較公正c.controls.password.valuec.controls.password2.value但因爲使用的是Md5,我只是在這裏使用了這些值。另外請注意,我們只是發送一個包含您選擇的自定義錯誤的對象,如果密碼不匹配,此處爲notSame

,並顯示錯誤信息,你可以這樣做:

<div *ngIf="form.hasError('notSame')">Passwords do not match!</div> 

你修改StackBlitz