无法访问嵌套表单值来验证表单
Can't access to nested forms values to validate form
我在 Angular 中使用响应式表单验证嵌套表单时遇到问题。我有一个可以正常工作的注册表单,但是在我添加表单组以分别检查有效性后,我收到了一些错误。这些错误是因为验证器只在主窗体上工作,而不在嵌套窗体上工作。我试图访问嵌套表单的值,但我发现表单的值未定义。
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 表单)无效,我该如何禁用按钮。
感谢您一如既往的帮助!
请查看 我给出了一个比较两个同级 formControl 的几乎相似的问题。
基于此,
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
中以表示为这 2 个控件新创建的包装 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
表单组基本相同。如果这就是您表格中的全部内容,您也可以省略两者中的任何一个。因此,您可以使用 myForm
或特定 emailPass
formGroup 的 valid
标志来检查表单的有效性,如下所示,
<button md-raised-button type="submit" [disabled]="!myForm.valid">Siguiente</button>
或
<button md-raised-button type="submit" [disabled]="!myForm.get('emailPass').valid">Siguiente</button>
希望对您有所帮助。
我在 Angular 中使用响应式表单验证嵌套表单时遇到问题。我有一个可以正常工作的注册表单,但是在我添加表单组以分别检查有效性后,我收到了一些错误。这些错误是因为验证器只在主窗体上工作,而不在嵌套窗体上工作。我试图访问嵌套表单的值,但我发现表单的值未定义。
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 表单)无效,我该如何禁用按钮。
感谢您一如既往的帮助!
请查看
基于此,
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
中以表示为这 2 个控件新创建的包装 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
表单组基本相同。如果这就是您表格中的全部内容,您也可以省略两者中的任何一个。因此,您可以使用 myForm
或特定 emailPass
formGroup 的 valid
标志来检查表单的有效性,如下所示,
<button md-raised-button type="submit" [disabled]="!myForm.valid">Siguiente</button>
或
<button md-raised-button type="submit" [disabled]="!myForm.get('emailPass').valid">Siguiente</button>
希望对您有所帮助。