Angular 2表格验证

时间:2018-03-02 18:33:07

标签: angular validation angular2-forms

我有使用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在调用(更改)envent之前调用自定义验证函数。为此,验证没有预期的行为。我怎么解决这个问题?有没有办法通过控制传递表单数组的索引?或者,在cheange事件之后总是调用验证函数?

2 个答案:

答案 0 :(得分:0)

你唯一想要的是索引,你可以使用父

获得它
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);
      }
    }

答案 1 :(得分:0)

使用Angular进行表单验证将验证与组件相结合。

这导致围绕验证的业务逻辑分散在组件中的整个应用程序中。

很多时候最好是创建基于TypeScript的可重用验证服务

  • 这允许业务逻辑集中在一个地方。

  • 您可以通过单元测试服务来对此业务逻辑进行单元测试。

这个演示Angular 6 CLI应用程序向您展示了如何执行此操作。

https://github.com/VeritasSoftware/ts-validator-app-angular6

您可能会发现这在您的设计考虑中很有用。