【问题标题】:Cannot read property of undefined Reactive Forms无法读取未定义反应形式的属性
【发布时间】:2019-02-13 14:22:43
【问题描述】:

我正在尝试为密码制作自定义验证器,但我不明白为什么会出现以下错误 错误类型错误:无法读取未定义的属性“f”

下面是我的代码:

registerForm: FormGroup;
submitted = false;
constructor(private Auth:AuthService, private router:Router,private 
formBuilder:FormBuilder) { }

ngOnInit() {
this.registerForm = this.formBuilder.group({
  userName: ['', Validators.compose([Validators.required,Validators.minLength(6),Validators.maxLength(30),Validators.pattern('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$')])],
  email: ['', Validators.compose([Validators.required, Validators.email])],
  password: ['', Validators.compose([Validators.required, Validators.minLength(6)])],
  cpassword: ['', Validators.required,passwordMatch()] //paswordMatch triggers the error
},);
}

get f() { return this.registerForm.controls; }

function  passwordMatch() { 
if(this.f != undefined){
let passwordInput = this.f.password,
   passwordConfirmationInput = this.f.cpassword;
if (passwordInput.value !== passwordConfirmationInput.value) {
 return passwordConfirmationInput.setErrors({notequal: true})
}
else {
   return passwordConfirmationInput.setErrors(null);
}
}
}

【问题讨论】:

  • 只使用passwordMatch() 而不是function passwordMatch()
  • 我使用函数是因为密码匹配在组件类之外
  • 这不会影响您的f 范围吗?
  • 我照你说的做了,还是一样的错误,不管我声明那个方法或函数还是一样的输出
  • 我会为密码创建一个子组并在那里应用验证器。因为如果用户在输入确认后更改了第一个密码怎么办。即使密码不匹配,表单也是有效的。

标签: angular typescript angular-reactive-forms


【解决方案1】:

this 在你的函数中是undefined,因此你不能引用它。

我要添加一个子表单组,它会跟踪密码的值和确认密码,但是如果你想走这条路,请修改你的代码:

// ...
// see the brackets also around the validators! No need to use Validators.compose
cpassword: ['', [Validators.required, passwordMatch]]
// ...

然后您将使用parent 访问表单组。您还需要返回null(有效)或错误:

function passwordMatch(input: FormControl) {
  if (input.parent) {
    let passwordInput = input.parent.get('password');
    if (passwordInput.value !== input.value) {
      return { notequal: true }
    }
    else {
      return null;
    }
  }
}

演示StackBlitz

但是,我们需要记住,如果用户在修改确认密码后修改了密码字段并且密码不匹配,那么表单仍然会被认为是有效的。这是避免这种情况的一种方法:password and confirm password field validation angular2 reactive forms

【讨论】:

  • 对不起,我需要休息一下,我会创建一个子组,但要输入密码并确认密码,但首先我想看到这个工作但仍然没有,我更新了你的方法说,我得到以下错误:错误错误:预期的验证器返回承诺或可观察。
  • 好吧,好像忘了放括号,一切都很好,对不起,我正在努力学习 Angular,今天在 PC 上花了太多时间,我累了,谢谢你的帮助。
  • 没问题,加布里埃尔,很高兴我能帮上忙。周末愉快,休息一下:P
  • 你能帮我多理解嵌套组是如何工作的吗?我的 html 组件中是否应该有一个不同的实现,除了让我们说:创建一个
    并在 div 内部实现密码和 cpassword 的表单组以及 div 末尾的 ofc 以有另一个 div 用于显示错误,除了我上面提到的内容之外,我是否应该更改一些内容?
  • 更容易展示,这个应该很清楚了吧? stackblitz.com/edit/angular-69peym?file=src/app/…根据我从您的评论中收集到的信息,您似乎完全走在正确的轨道上:)
【解决方案2】:

您可以使用 input .root 来访问控件的父级(您的 registerForm)试试这个,不需要 f 函数

 function  passwordMatch(input: FormControl) { 
  if(input.root != undefined){
  let passwordInput = input.root.controls.password,
  passwordConfirmationInput = input.root.controls.cpassword;
  if (passwordInput.value !== passwordConfirmationInput.value) {
   return passwordConfirmationInput.setErrors({notequal: true})
  }
  else {
    return passwordConfirmationInput.setErrors(null);
  }
 }

...

cpassword: ['', Validators.required, passwordMatch]

【讨论】:

  • 我在编译时收到一个错误,即控件不是 AbstractControl 的属性
  • 试试 input.root['controls'] 而不是 .controls
  • 我在输入确认密码字段时收到此错误错误错误:预期验证器返回 Promise 或 Observable。我的验证器方法有问题吗?
  • 我发现了问题所在,之前已经再次遇到了这个问题,但是在你说的所有更改之后我没有编译错误但该函数仍然抛出错误,无法读取未定义的密码...
猜你喜欢
相关资源
最近更新 更多
热门标签