Angular 2 表单验证
Angular 2 Form Validation
我有这个表格使用 Angular 2:
<form [formGroup]="form">
<div formArrayName="passageiros">
<div *ngFor="let passageiro of form.get('passageiros')['controls']; let i=index">
<div [formGroupName]="i">
<div class="row">
<div class="col-md-2">
<h3><strong ngDefaultControl>{{ModPassageiros[i].NomeTipoPassageiro}} {{i + 1}}:</strong></h3>
</div>
<div class="col-md-2">
<mat-input-container style="width: 100%">
<input matInput [matDatepicker]="picker" placeholder="Data Nasc" [max]="maxDataNasc" formControlName="DataNascimento" name="DataNascimento" [(ngModel)]="ModPassageiros[i].DataNascimento" (dateInput)="pegaIndice($event, i)" (dateChange)="pegaIndice($event, i)" required>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker ></mat-datepicker>
<mat-error *ngIf="!form.controls.passageiros.controls[i].controls.DataNascimento.valid && !form.controls.passageiros.controls[i].controls.DataNascimento.pristine " >
Insira uma data de nascimento válida e de acordo com o tipo de pessoa (Adulto, criança ou bebê).
</mat-error>
</mat-input-container>
</div>
</div>
</div>
</div>
</div>
</form>
我想根据乘客类型值验证出生日期。
这是类型脚本:
constructor(private fb:FormBuilder) {
this.form = this.fb.group({
passageiros: this.fb.array([
this.iniciaPassageiros(),
]),
}
)
}
iniciaPassageiros() {
return this.fb.group({
DataNascimento :[new Date(), Validators.compose([
Validators.required,
(control) => this.validarDataNascPorTipo(control, this.indicePassageiros)
])]
});
}
public pegaIndice(e, i)
{
this.indicePassageiros = i;
}
这是自定义验证器函数:
public validarDataNascPorTipo(control : AbstractControl, i)
{
let dias : number = this.util.calcularDias(control.value);
if(this.ModPassageiros[i])
{
if(this.ModPassageiros[i].Tipo == 'ADT' && dias < 4015)
return {"Data nascimento não é de " : true
if(this.Tipo == 'INF' && dias > 700)
return { "Data nascimento não é de ' + this.schemaJson.Metadados.Modelos.ModPassageiros[i].Tipo + '(abaixo de 23 meses)." : true }
if(this.ModPassageiros[i].Tipo == 'CHD' && (dias > 4014 || dias < 700))
return { "Data nascimento não é de ' + this.schemaJson.Metadados.Modelos.ModPassageiros[i].Tipo + '(acima 23 meses e até de 11 anos)." : true};
}
return null;
}
我正在尝试传递实际索引以验证正确的控件,但 angular 在(更改)事件之前调用自定义验证函数。为此,验证没有预期的行为。我怎么解决这个问题?有没有办法通过控件传递表单数组的索引?或者,总是在更改事件之后调用验证函数?
由于您唯一需要的是索引,因此您可以使用父级获取它
iniciaPassageiros() {
return this.fb.group({
DataNascimento :[new Date(), [Validators.required,this.customValidator]
});
}
customValidator(control) {
if (control) {
let fbgroup = control.parent; //<--the FormGroup
if (fbgroup) {
let fbarray=fbgroup.parent; //<--the FormArray
let index=fbarray.controls.indexOf(fbgroup);
}
}
表单验证 Angular 将验证与组件相结合。
这导致围绕验证的业务逻辑分散在组件中的整个应用程序中。
很多时候最好创建一个基于 TypeScript 的可重复使用的验证服务。
这使得业务逻辑可以集中在一个地方。
您可以通过对服务进行单元测试来对该业务逻辑进行单元测试。
此 演示 Angular 6 CLI 应用程序 向您展示了如何执行此操作。
https://github.com/VeritasSoftware/ts-validator-app-angular6
根据您的设计考虑,您可能会发现这很有用。
我有这个表格使用 Angular 2:
<form [formGroup]="form">
<div formArrayName="passageiros">
<div *ngFor="let passageiro of form.get('passageiros')['controls']; let i=index">
<div [formGroupName]="i">
<div class="row">
<div class="col-md-2">
<h3><strong ngDefaultControl>{{ModPassageiros[i].NomeTipoPassageiro}} {{i + 1}}:</strong></h3>
</div>
<div class="col-md-2">
<mat-input-container style="width: 100%">
<input matInput [matDatepicker]="picker" placeholder="Data Nasc" [max]="maxDataNasc" formControlName="DataNascimento" name="DataNascimento" [(ngModel)]="ModPassageiros[i].DataNascimento" (dateInput)="pegaIndice($event, i)" (dateChange)="pegaIndice($event, i)" required>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker ></mat-datepicker>
<mat-error *ngIf="!form.controls.passageiros.controls[i].controls.DataNascimento.valid && !form.controls.passageiros.controls[i].controls.DataNascimento.pristine " >
Insira uma data de nascimento válida e de acordo com o tipo de pessoa (Adulto, criança ou bebê).
</mat-error>
</mat-input-container>
</div>
</div>
</div>
</div>
</div>
</form>
我想根据乘客类型值验证出生日期。
这是类型脚本:
constructor(private fb:FormBuilder) {
this.form = this.fb.group({
passageiros: this.fb.array([
this.iniciaPassageiros(),
]),
}
)
}
iniciaPassageiros() {
return this.fb.group({
DataNascimento :[new Date(), Validators.compose([
Validators.required,
(control) => this.validarDataNascPorTipo(control, this.indicePassageiros)
])]
});
}
public pegaIndice(e, i)
{
this.indicePassageiros = i;
}
这是自定义验证器函数:
public validarDataNascPorTipo(control : AbstractControl, i)
{
let dias : number = this.util.calcularDias(control.value);
if(this.ModPassageiros[i])
{
if(this.ModPassageiros[i].Tipo == 'ADT' && dias < 4015)
return {"Data nascimento não é de " : true
if(this.Tipo == 'INF' && dias > 700)
return { "Data nascimento não é de ' + this.schemaJson.Metadados.Modelos.ModPassageiros[i].Tipo + '(abaixo de 23 meses)." : true }
if(this.ModPassageiros[i].Tipo == 'CHD' && (dias > 4014 || dias < 700))
return { "Data nascimento não é de ' + this.schemaJson.Metadados.Modelos.ModPassageiros[i].Tipo + '(acima 23 meses e até de 11 anos)." : true};
}
return null;
}
我正在尝试传递实际索引以验证正确的控件,但 angular 在(更改)事件之前调用自定义验证函数。为此,验证没有预期的行为。我怎么解决这个问题?有没有办法通过控件传递表单数组的索引?或者,总是在更改事件之后调用验证函数?
由于您唯一需要的是索引,因此您可以使用父级获取它
iniciaPassageiros() {
return this.fb.group({
DataNascimento :[new Date(), [Validators.required,this.customValidator]
});
}
customValidator(control) {
if (control) {
let fbgroup = control.parent; //<--the FormGroup
if (fbgroup) {
let fbarray=fbgroup.parent; //<--the FormArray
let index=fbarray.controls.indexOf(fbgroup);
}
}
表单验证 Angular 将验证与组件相结合。
这导致围绕验证的业务逻辑分散在组件中的整个应用程序中。
很多时候最好创建一个基于 TypeScript 的可重复使用的验证服务。
这使得业务逻辑可以集中在一个地方。
您可以通过对服务进行单元测试来对该业务逻辑进行单元测试。
此 演示 Angular 6 CLI 应用程序 向您展示了如何执行此操作。
https://github.com/VeritasSoftware/ts-validator-app-angular6
根据您的设计考虑,您可能会发现这很有用。