web-dev-qa-db-fra.com

Comment valider la longueur de FormArray dans angular2

J'ai une forme pilotée par les données dans angular2 comme ci-dessous

this.formBuilder.group({
  'name': ['',Validators.required],
  'description': ['', Validators.required],
  'places': this.formBuilder.array([], Validators.minlength(1)) 
})

Je veux ajouter des validations à la place formArray. Je rajoute donc la validation minlength, mais la validation minlength ne fonctionne pas sur formArray.

Quelles sont les autres validations pour formArray, de sorte que le formulaire ne doit être valide que lorsque le tableau d'endroits contient au moins un emplacement.

16
Chandra Shekhar

Ajoutez ce validateur personnalisé à votre service de validation:

minLengthArray(min: number) {
    return (c: AbstractControl): {[key: string]: any} => {
        if (c.value.length >= min)
            return null;

        return { 'minLengthArray': {valid: false }};
    }
}

Et ensuite, lors de la création du formulaire, procédez comme suit:

this.formBuilder.group({
  'name': ['',Validators.required],
  'description': ['', Validators.required],
  'places': this.formBuilder.array([], this.validationService.minLengthArray(1)) 
});

Et vous pouvez vérifier les erreurs par rapport à FormArray en cochant FormArray.hasError('minLengthArray')

20
user1779362

Validators.required fait la magie pour vous:

this.formGroup = this.formBuilder.group({
    taskTreeId: [Common.UID()],
    executionProgrammedTime: ["", [Validators.required]],
    description: [""],
    tasks: this.formBuilder.array([], Validators.required)
});
<button type="button" class="btn btn-success btn-rounded" 
    [disabled]="!formGroup.valid">SAVE</button>
18
Javier González

parce que vous utilisez un nom de fonction de validation incorrect: minlength -> minLength

code de démonstration:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms';

@Component({
  selector: 'app-root',
  template: `
    <form novalidate [formGroup]="tpForm" (ngSubmit)="onSubmit()">
      <div><input type="text" formControlName="name"></div>
      <div><textarea formControlName="description"></textarea></div>
      <div formArrayName="places">
        <button type="button" (click)="addPlace()">+</button>
        <div *ngFor="let place of places.controls; let i = index">
          <div>
              <span>Places {{i + 1}}</span>
              <button type="button" *ngIf="places.controls.length > 0" 
                  (click)="removePlace(i)">
                  x
              </button>
          </div>
          <input type="text" [formControlName]="i">
        </div>
      </div>
      <button type="submit">Submit</button>
    </form>

    <p>Status: {{ tpForm.valid }}</p>
  `,
  styles: [
    `


    `
  ]
})
export class AppComponent implements OnInit {
  tpForm: FormGroup;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.tpForm = this.fb.group({
      'name': ['',Validators.required],
      'description': ['', Validators.required],
      'places': this.fb.array([
        this.fb.control('')
      ], Validators.minLength(1))
    })
  }

  get places(): FormArray {
    return this.tpForm.get('places') as FormArray;
  }

  onSubmit() {

  }

  addPlace() {
    this.places.Push(this.fb.control(''));
  }

  removePlace(index) {
    this.places.removeAt(index);
  }

}

Plunker: https://plnkr.co/edit/cfi7nN?p=preview

6
Tiep Phan

si vous essayez d’ajouter une validation à formarray, cela peut vous aider,

this.formBuilder.group({
  'name': ['',Validators.required],
  'description': ['', Validators.required],
  'places': this.formBuilder.array(this.initPlaces()) 
})

initPlaces() {       
        return this._fb.group({
            places: ['',[Validators.minLength(1)]]           
        });
  }

cette initPlaces renverra simplement formGroup avec la validation selon l'exigence.

3
Pardeep Jain

Bon et clair moyen de le faire est:

Créez un Array.validator.ts et placez toutes les validations personnalisées là-bas, comme minLength, maxLength etc.

import { ValidatorFn, AbstractControl, FormArray } from '@angular/forms';

// Array Validators
export class ArrayValidators {

    // max length
    public static maxLength(max: number): ValidatorFn | any {
        return (control: AbstractControl[]) => {
            if (!(control instanceof FormArray)) return;
            return control.length > max ? { maxLength: true } : null;
        }
    }

    // min length
    public static minLength(min: number): ValidatorFn | any {
        return (control: AbstractControl[]) => {
            if (!(control instanceof FormArray)) return;
            return control.length < min ? { minLength: true } : null;
        }
    }
}

Et puis, importez ce fichier et utilisez la validation où vous voulez:

import { ArrayValidators } from './array.validator'; // Import it

'hobbies':new FormArray([],ArrayValidators.minLength(2)) // Use it

DEMO DE TRAVAIL


Remarque :

Vous pouvez aussi utiliser ce paquet directement aussi ng-validator (la référence provient de ce paquet), mais si vous avez juste besoin des validations de tableau requises, vous pouvez le faire comme ci-dessus.

1
Vivek Doshi