简体   繁体   English

如何验证 angular2 中的 FormArray 长度

[英]How to Validate FormArray length in angular2

I have a data driven form in angular2 like below我有一个 angular2 中的数据驱动形式,如下所示

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

I want to add validations to the place formArray, so i am adding minlength validation, but minlength validation is not working on formArray.我想向 formArray place添加验证,所以我添加了minlength验证,但 minlength 验证不适用于 formArray。

What are the other validations for formArray, so that form must be valid only when places array contain atleast one place. formArray 的其他验证是什么,因此该表单必须仅在 Places 数组包含至少一个位置时有效。

Validators.required does the magic for you: Validators.required为你做魔法:

// using required 

this.formGroup = this.formBuilder.group({
    taskTreeId: [Common.UID()],
    executionProgrammedTime: ["", [Validators.required]],
    description: [""],
    tasks: this.formBuilder.array([], Validators.required)
});  

// using custom validation

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

    return { MinLengthArray: true};
  }
}

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

Add this custom validator to your validation service:将此自定义验证器添加到您的验证服务中:

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

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

And then when creating the form do the following:然后在创建表单时执行以下操作:

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

And you can check errors against the FormArray by checking FormArray.hasError('minLengthArray')你可以核对错误FormArray通过检查FormArray.hasError('minLengthArray')

because you using wrong validator function name: minlength -> minLength因为您使用了错误的验证器函数名称: minlength -> minLength

demo code:演示代码:

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 Plunker: https ://plnkr.co/edit/cfi7nN ? p = preview

Good and clear way to do this is :这样做的好方法是:

Create a Array.validator.ts and put all the custom validations over there , like minLength , maxLength etc创建一个Array.validator.ts并将所有自定义验证放在那里,例如minLengthmaxLength

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

And Then just import that file and use validation wherever you want to :然后只需导入该文件并在您想要的任何地方使用验证:

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

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

WORKING DEMO 工作演示


Note :笔记 :

You can directly use this package also ng-validator ( Reference is taken from this package ) , But If you need just required array validations you can do it like above.你也可以直接使用这个包ng-validator (参考来自这个包),但是如果你只需要所需的数组验证,你可以像上面那样做。

if you are trying to add validation to formarray try this may help you,如果您尝试向 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)]]           
        });
  }

this initPlaces will simply return formGroup with validation as per requirement.这个initPlaces将根据要求简单地返回带有验证的 formGroup 。

Having a template有模板

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

    [...]

    </div>
</div>

You could simply use this in your button :你可以简单地在你的按钮中使用它:

[disabled]="!myForm.get('items.1')"
this.profileForm = this.fb.group({
      firstName: [''],
      lastName: [''],
      hobbies: this.fb.array([this.fb.control('')], Validators.minLength(2))
});

Just use the Validators.minLength(length) .只需使用Validators.minLength(length) https://angular.io/api/forms/Validators#minLength https://angular.io/api/forms/Validators#minLength

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM