3
votes

Validation personnalisée Angular 7 avec paramètre dynamique / mis à jour

J'utilise angular 7 avec des composants de conception de matériaux

J'ai besoin d'ajouter la validation requireMatch à mat-autocomplete.

J'ai créé une validation personnalisée avec param mais la valeur de param change dynamiquement. p>

Voici le code de mon composant.

this.stepFormGroup = this.formBuilder.group({
    AccessCode: ["", [Validators.required, this.requireMatch(this.accessCodeList)]]
});

////require-match validation for access-code
requireMatch = (accessCodes: string[]) => {
    return (control: FormControl) => {
        const selection: any = control.value;
        console.log("accessCodes", accessCodes, "selection", selection);
        if (accessCodes.indexOf(selection)===-1) {
            return { requireMatch: true };
        }
        return null;
    }
}

Problème auquel je suis confronté: je suis toujours vide (init) dans accessCodes à l'intérieur de requireMatch .

Les changements de this.accessCodeList ne reflètent pas le validateur.

Cela signifie qu'après avoir changé this.accessCodeList , le tableau n'est pas mis à jour dans le validateur requireMatch .

Donc, tout le monde a une idée sur la façon de passer le paramètre dynamique dans custom-validator?


13 commentaires

Pouvez-vous fournir stackblitz /


Et aussi la question n'est pas claire--) Décrivez simplement ce que vous voulez? et ce qui ne fonctionne pas actuellement


Cela fonctionne bien: stackblitz.com/edit/angular-9nggzx


Je pense que vous devez utiliser, lorsque vous modifiez "this.accessCodeList", this.stepFormGroup.get ('AccessCode'). SetValidators ([Validato‌ rs.required, this.requireMatch (this.accessCodeList)])


Je fogot, utilisez this.stepFormGroup.get ('AccessCode'). UpdateValueAndValidity (‌) après avoir changé le validateur


@Eliseo J'ai utilisé le code ci-dessus après les modifications de la valeur de this.accessCodeList . La liste n'est toujours pas mise à jour dans le validateur


Si this.accessCodeList change, vous devez redéfinir les validateurs.


@MullisS Pouvez-vous me dire comment modifier à nouveau le validateur d'ensemble d'un champ spécifique avec une valeur mise à jour?


voir stackblitz.com/edit/angular-pxez4f?file = src / app /… (Vous avez une erreur de type, l'index peut être 0 lorsqu'il correspond au premier élément)


Voici une solution de travail: stackblitz.com/edit/angular-9nggzx


@Eliseo J'ai mis à jour la question. mon problème je ne suis pas mis à jour this.accessCodeList dans le validateur


@MullisS, changez la condition, ce n'est pas accessCodes.indexOf (sélection), c'est accessCodes.indexOf (sélection) <0


@MullisS Votre exemple a fonctionné. Merci.


3 Réponses :


1
votes

Selon mon hypothèse, vous souhaitez comparer l'entrée utilisateur avec le tableau de chaînes avec le FormControl. Ainsi, vous pouvez obtenir l'index d'un élément et vérifier s'il n'est pas égal à -1 comme:

<input [formControl]="stepFormGroup.get('AccessCode')">

Code TS:

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

@Component({
  selector: 'select-multiple-example',
  templateUrl: 'select-multiple-example.html',
  styleUrls: ['select-multiple-example.css'],
})
export class SelectMultipleExample implements OnInit {
  public stepFormGroup: FormGroup;
  accessCodeList: any[] = ['Prashant', 'Pimpale'];

  constructor(private fb: FormBuilder) {

  }

  public ngOnInit(): void {
    this.stepFormGroup = this.fb.group({
      AccessCode: ["", [Validators.required, this.requireMatch(this.accessCodeList)]]
    });
  }

  ////require-match validation for access-code
  requireMatch = (accessCodes: string[]) => {
    return (control: FormControl) => {
      const selection: any = control.value;

      console.log("accessCodes", accessCodes, "selection", selection);
      var index = accessCodes.indexOf(selection);
      if (index != -1) {
        console.log('if')
        return { requireMatch: true };
      }
      else {
        // console.log('else')
        return null;
      }
      return null;
    }
  }
}

Code HTML:

var index = accessCodes.indexOf(selection);
if (index != -1) { // That means item found in the array
  console.log('if')
  return { requireMatch: true };
}
else {
  // console.log('esle')
  return null;
}

StackBlitz


4 commentaires

Je pense que le problème est qu'Ankur veut changer le accessCodeList APRÈS avoir créé le formulaire. Il doit donc utiliser setValidators


@Eliseo Oui, peut-être! Lui a demandé des éclaircissements mais il n'a pas répondu


Oui. Je sais que la valeur changera lors de la recherche car le composant est auto-complet


@AnkurAkvaliya Veuillez modifier la question et indiquer vos besoins



3
votes

Vous devez lier la fonction de validation lorsque vous l'appelez comme ceci, sinon la fonction de validation ne liera pas l'entrée accessList

[Validators.required, this.requireMatch(this.accessCodeList).bind(this)]

Aussi si vous voulez restreindre un mot dans le champ, vous pouvez avoir regardez l'un de mes packages npm ici https://www.npmjs.com/package/ng4- validation


2 commentaires

Ceci fournit un moyen d'accéder à tous les paramètres du composant. Merci mec!


Étrangement, ma variable passée reste nulle.



2
votes

Pour faire fonctionner votre validateur avec la dernière valeur du contrôleur, vous pouvez le transmettre en tant que fonction et le résoudre chaque fois que cela est nécessaire. afin que votre fonction de validation obtienne la dernière valeur ou la valeur actuelle.

Le code ci-dessous vous donnera un aperçu de ma réponse

// Component 
this.stepFormGroup = this.formBuilder.group({
    AccessCode: ["", [Validators.required, this.requireMatch(() => this.accessCodeList)]]
});

//Validator Function
requireMatch = (getAccessCodes: (() => string[])) => {
    return (control: FormControl) => {
        const selection: any = control.value;
        const accessCodes = getAccessCodes();
        console.log("accessCodes", accessCodes, "selection", selection);
        if (accessCodes.indexOf(selection)===-1) {
            return { requireMatch: true };
        }
        return null;
    }
}


0 commentaires