开发者问题收集

表单值对象为什么是空的?

2017-12-27
6235

请帮忙理解。我正在尝试为反应式表单编写自定义验证器。

组件:

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

此处有实时示例

2个回答

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])
});
Wallace
2017-12-27

除了将初始值设为 null 之外,您还在 formcontrol 上设置了自定义验证器,因此您在自定义验证器中实际获得的只是 formcontrol password2 而不是 整个 formgroup。

因此,我会将自定义验证器放在 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

AVJT82
2017-12-28