web-dev-qa-db-fra.com

Angular2: savoir si FormControl a requis un validateur?

quelqu'un connaît-il un moyen de rechercher un Angular2 FormControl si le valideur requis est enregistré pour le contrôle?.

this.form = builder.group({name: ['', Validators.required]};

Puis-je alors interroger le this.form.controls['name'] contrôler s'il s'agit d'un champ obligatoire? Je sais que je peux vérifier si elle est valide, mais ce n'est pas ce que je veux.

Cordialement, Marc

39
Marc

Cette fonction devrait fonctionner pour FormGroups et FormControls

  export const hasRequiredField = (abstractControl: AbstractControl): boolean => {
    if (abstractControl.validator) {
        const validator = abstractControl.validator({}as AbstractControl);
        if (validator && validator.required) {
            return true;
        }
    }
    if (abstractControl['controls']) {
        for (const controlName in abstractControl['controls']) {
            if (abstractControl['controls'][controlName]) {
                if (hasRequiredField(abstractControl['controls'][controlName])) {
                    return true;
                }
            }
        }
    }
    return false;
};
52
Marcel Tinner

Bien qu'il n'y ait pas Angular API pour trouver directement si le validateur required est défini pour un champ particulier, la manière détournée pour y parvenir est comme ci-dessous:

import { NgForm, FormControl } from '@angular/forms';

const isRequiredControl = (formGroup: NgForm, controlName: string): boolean => {
    const { controls } = formGroup
    const control = controls[controlName]
    const { validator } = control
    if (validator) {
        const validation = validator(new FormControl())
        return validation !== null && validation.required === true
    }
    return false
}

J'ai testé ceci et cela ne se déclenche que si le Validator.Required le validateur est ajouté au FormControl particulier.

6
Aragorn

J'ai un problème similaire. Pour l'instant, j'utilise ceci:

  import { Attribute } from '@angular/core';

  // "Kind-of" hack to allow "pass-through" of the required attribute
  constructor(@Attribute('required') public required) {
    // call super here if the component is an ancestor
  }

Je suis vraiment perplexe quant à la raison pour laquelle des propriétés comme "désactivées" sont incluses dans FormControl, mais pas "obligatoires".

2
Dave Nottage

Il n'y a pas de méthode pour vérifier les validateurs ou obtenir tous les validateurs: https://github.com/angular/angular/issues/13461

La solution @ fairlie-agile est assez intelligente. Mais je pense que nous devons utiliser FormControl vide parce que nous avons besoin du validateur requis par le feu et this.group.controls[this.config.name] pourrait déjà être initialisé avec une certaine valeur.

ngOnInit() {
    let formControl = this.group.controls[this.config.name];
    let errors: any = formControl.validator && formControl.validator(new FormControl());
    this._required = errors !== null && errors.required;
}
2
vlapo21

Une façon de procéder consiste à vérifier si le contrôle est valide lorsque le formulaire est chargé pour voir s'il contient l'erreur requise (ce qu'il sera si le champ est vide).

Cela ne fonctionnera pas pour d'autres validateurs, tels que minLength, car ils ne sont pas déclenchés tant que le contrôle n'est pas modifié

export class FormInputComponent implements Field, OnInit {
  private _required: boolean;
  config: FieldConfig;
  group: FormGroup;

    /** Readonly properties. */
  get required(): boolean { 
    return this._required;
  }

  ngOnInit() {
    var _validator: any = this.group.controls[this.config.name].validator && this.group.controls[this.config.name].validator(this.group.controls[this.config.name]);
    this._required = _validator && _validator.required;
  }
}
1
Fairlie Agile

En supposant que la seule erreur enregistrée initialement est l'erreur required

// in your component you'll have access to `this.myFormGroup`
const formGroup = {
  controls: {
    email: {
      errors: {
        required: true
      }
    },
    username: {
      errors: null
    }    
  }
}

// required by default
let required = {
  email: '*',
  username: '*',
};

// in `ngOnInit`
required = Object.entries(formGroup.controls)
  .map(([key, control]) => [key, control.errors])
  .filter(([, errors]) => !errors)
  .map(([key]) => [key, ''])
  .reduce((_required, [key, isRequired]) => Object.assign(_required, { [key]: isRequired }), required)

// in your template you may write `<label>Email{{ required.email }}</label>`
console.log(required)
0
Mateja Petrovic