我在使用Angular中的Reactive Forms验证嵌套表单时遇到问题。我有一个正常工作的注册表单,但在我添加表单组以分别检查有效性后,我遇到了一些错误。这些错误是因为验证器只在主窗体上工作,而不是嵌套的验证器。我试图访问嵌套表单的值,但我得到的是表单的值未定义。
component.ts
import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup, Validators, FormControl } from "@angular/forms";
@Component({
selector: 'my-page-sign-up',
styleUrls: ['./sign-up.component.scss'],
templateUrl: './sign-up.component.html'
})
export class PageSignUpComponent implements OnInit {
myForm: FormGroup;
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
'emailPass': this.fb.group({
email: ['', [
Validators.required,
Validators.email
]],
password: ['', Validators.required],
confirmPassword: ['', Validators.compose([
Validators.required,
this.isEqualPassword.bind(this)
])],
}),
})
}
isEqualPassword(control: FormControl): {[s: string]: boolean} {
if (!this.myForm.controls) {
return {passwordsNotMatch: true};
}
if (control.value !== this.myForm.controls['password'].value) {
return {passwordsNotMatch: true};
}
}
}
HTML
<form [formGroup]="myForm" (ngSubmit)="onSignup()">
<div formGroupName="emailPass" class="form-group">
<md-input-container class="col-md-6 md-icon-left">
<md-icon class="material-icons">mail_outline</md-icon>
<input formControlName="email" mdInput #email type="email" name="email" class="form-control" placeholder="Email">
<!--md-hint *ngIf="!myForm.get(['emailPass', 'email']).pristine && myForm.hasError('noEmail', 'email')">Invalid mail address</md-hint-->
</md-input-container>
<md-input-container class="col-md-6 md-icon-left no-margin-bottom">
<md-icon class="material-icons">lock_outline</md-icon>
<input required mdInput formControlName="password" type="password" class="form-control" id="password" name="password" placeholder="Contraseña">
</md-input-container>
<md-input-container class="col-md-6 md-icon-left no-margin-bottom">
<md-icon class="material-icons">lock_outline</md-icon>
<input required mdInput type="password" formControlName="confirmPassword" class="form-control" name="password" placeholder="Confirmar Contraseña">
</md-input-container>
</div>
<button md-raised-button type="submit">Siguiente</button>
所以,我有两个问题。第一个是如何修复我正在尝试验证密码和电子邮件的错误。第二个是知道如果嵌套表单(emailPass表单)无效,我如何禁用该按钮。
感谢您一如既往的帮助!
答案 0 :(得分:2)
请查看this answer我提供了一个几乎相似的问题,比较了两个同级的formControls。
基于此,
import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup, Validators, FormControl } from "@angular/forms";
function isEqualPassword(control: AbstractControl): {[s: string]: boolean} {
if (!control.get('password') || !control.get('confirmPassword')) {
return null; // returning validity true if either one of the controls not present - safety check on initial load
}
return control.get('password').value === control.get('confirmPassword').value ? null : {passwordsNotMatch: true};
}
@Component({
selector: 'my-page-sign-up',
styleUrls: ['./sign-up.component.scss'],
templateUrl: './sign-up.component.html'
})
export class PageSignUpComponent implements OnInit {
myForm: FormGroup;
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
emailPass: this.fb.group({
email: ['', [
Validators.required,
Validators.email
]],
passwordsCtrl: this.fb.group({
password: ['', Validators.required],
confirmPassword: ['', Validators.required]
}, { validator: isEqualPassword }
})
})
})
}
}
然后将您的密码相关控件包装在另一个div
或类似的(您的选择)另一个formGroupName
中,以表示这两个控件的新创建的包装formGroup。
<form [formGroup]="myForm" (ngSubmit)="onSignup()">
<div formGroupName="emailPass" class="form-group">
<md-input-container class="col-md-6 md-icon-left">
<md-icon class="material-icons">mail_outline</md-icon>
<input formControlName="email" mdInput #email type="email" name="email" class="form-control" placeholder="Email">
<!--md-hint *ngIf="!myForm.get(['emailPass', 'email']).pristine && myForm.hasError('noEmail', 'email')">Invalid mail address</md-hint-->
</md-input-container>
<div formGroupName="passwordsCtrl">
<md-input-container class="col-md-6 md-icon-left no-margin-bottom">
<md-icon class="material-icons">lock_outline</md-icon>
<input required mdInput formControlName="password" type="password" class="form-control" id="password" name="password" placeholder="Contraseña">
</md-input-container>
<md-input-container class="col-md-6 md-icon-left no-margin-bottom">
<md-icon class="material-icons">lock_outline</md-icon>
<input required mdInput type="password" formControlName="confirmPassword" class="form-control" name="password" placeholder="Confirmar Contraseña">
</md-input-container>
</div>
</div>
<button md-raised-button type="submit">Siguiente</button>
关于禁用该按钮,您的myForm
和emailPass
formGroups基本相同。如果这就是你的形式,你也可以省略其中一个。因此,您可以使用valid
的{{1}}标记或特定的myForm
formGroup来检查表单的有效性,
emailPass
或
<button md-raised-button type="submit" [disabled]="!myForm.valid">Siguiente</button>
希望它有所帮助。