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