Как проверить длину FormArray в angular2

У меня есть форма данных с данными в angular2, как показано ниже

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

Я хочу добавить проверки в форму place formArray, поэтому я добавляю проверку minlength, но проверка длины minlength не работает на formArray.

Каковы другие проверки для formArray, так что форма должна быть действительной только тогда, когда массив объектов содержит по крайней мере одно место.

Ответ 1

Validators.required делает волшебство для вас:

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>

Ответ 2

Добавьте этот специальный валидатор в службу проверки:

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

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

И затем при создании формы выполните следующие действия:

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

И вы можете проверить ошибки на FormArray, проверив FormArray.hasError('minLengthArray')

Ответ 3

потому что вы используете неправильное имя функции валидатора: minlengthminlength

демо-код:

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

Ответ 4

если вы пытаетесь добавить валидацию в formarray, попробуйте, это может вам помочь,

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

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

этот initPlaces будет просто возвращать formGroup с проверкой согласно требованию.

Ответ 5

Хороший и понятный способ сделать это:

Создайте Array.validator.ts и поместите Array.validator.ts все пользовательские проверки, такие как minLength, maxLength т.д.

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;
        }
    }
}

А затем просто импортируйте этот файл и используйте проверку везде, где вы хотите:

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

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

РАБОЧАЯ ДЕМО


Замечания:

Вы можете напрямую использовать этот пакет также ng-validator (ссылка взята из этого пакета), но если вам нужны только необходимые проверки массивов, вы можете сделать это, как описано выше.

Ответ 6

Наличие шаблона

<div formArrayName="items">
    <div *ngFor="[...] let i = index" [formGroupName]="i">

    [...]

    </div>
</div>

Вы можете просто использовать это в своей кнопке:

[disabled]="!myForm.get('items.1')"