Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 无法读取未定义的被动窗体的属性_Angular_Typescript_Angular Reactive Forms - Fatal编程技术网

Angular 无法读取未定义的被动窗体的属性

Angular 无法读取未定义的被动窗体的属性,angular,typescript,angular-reactive-forms,Angular,Typescript,Angular Reactive Forms,我正在尝试为密码创建一个自定义验证器,但我不明白为什么会出现以下错误 错误类型错误:无法读取未定义的属性“f” 下面是我的代码: registerForm: FormGroup; submitted = false; constructor(private Auth:AuthService, private router:Router,private formBuilder:FormBuilder) { } ngOnInit() { this.registerForm = this.form

我正在尝试为密码创建一个自定义验证器,但我不明白为什么会出现以下错误 错误类型错误:无法读取未定义的属性“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);
}
}
}

您可以使用input.root访问控件的父控件(您的RegisterPerform)试试这个,不需要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);
  }
 }


在您的函数中是
未定义的
,因此您无法引用它

我将添加一个子表单组,它将跟踪password和confirm password的值,但是如果您想走这条路线,请修改您的代码如下:

// ...
// see the brackets also around the validators! No need to use Validators.compose
cpassword: ['', [Validators.required, passwordMatch]]
// ...
然后,您将使用
父项
访问表单组。您还需要返回
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;
    }
  }
}
演示


但是有了这个,我们需要记住,如果用户在修改confirmpassword之后修改了password字段,并且密码不匹配,那么表单仍然被认为是有效的。这里有一种避免这种情况的方法:

只需使用
passwordMatch()
而不是
函数passwordMatch()
我使用函数,因为passwordMatch在组件类之外,这不会影响
f
的范围吗?我按照你说的做了,仍然是相同的错误,无论我在何处声明该方法或函数,都会创建一个密码子组,并在那里应用验证器。因为如果用户在输入确认后更改第一个密码会怎么样。表单将是有效的,即使密码不匹配。我在编译时收到一个错误,该控件不是AbstractControltry input的属性。root['controls']而不是。controls我在输入确认密码字段时收到此错误错误错误:预期验证程序返回承诺或可观察。我的验证器方法有问题吗?我发现问题出在哪里了,早些时候又出现了这个问题,但在所有更改之后,正如你所说,我没有得到编译错误,但该函数仍在抛出错误,无法读取未定义的密码…很抱歉回答晚了,我需要休息一下,我将创建一个分组,但用于密码和确认密码,但首先我希望看到这一个工作,但仍然没有,我更新了方法,正如您所说,我得到了以下错误:错误错误:预期验证器返回承诺或可观察。好吧,似乎我忘了放一个括号,一切都很好,对不起,我正在努力学习,今天花了太多时间在电脑上,我很累,谢谢你的帮助。没问题,加布里埃尔,很高兴我能帮上忙。祝你周末愉快,休息一下:P你能帮我进一步了解嵌套组的工作方式吗?我的html组件中是否有不同的实现,比如:创建一个和内部div来实现密码和cpassword的表单组,以及div末尾的ofc来实现另一个div来显示错误,除了我上面提到的以外,我是否应该改变一些东西?更容易显示,这应该是非常清楚的?从我从你的评论中得到的信息来看,你似乎完全在正确的轨道上:)
function passwordMatch(input: FormControl) {
  if (input.parent) {
    let passwordInput = input.parent.get('password');
    if (passwordInput.value !== input.value) {
      return { notequal: true }
    }
    else {
      return null;
    }
  }
}