Question

J'essaie de créer des validations personnalisées pour les composants d'entrée personnalisés.

La directive de l'entrée personnalisée agirait comme une boîte noire, afin que je puisse ajouter les validations que je souhaite de la part du contrôleur.

Pour ce faire, j'ajoute un attribut pour la directive, appelé "validations", par exemple :

<custom-input validations="checkEmail() checkIsNotUsed()" type="text" placeholder="Email"></custom-input>

Avec cet exemple, je peux définir mes validations depuis le contrôleur comme je le souhaite, avec l'idée que lorsque je souhaite soumettre depuis le contrôleur, il vérifiera si ce composant est validé pour 'checkEmail()' et 'checkIsNotUsed()'.Pour ce faire, j'aurais besoin d'une communication bidirectionnelle entre le contrôleur et la directive interne, par exemple.en utilisant l'e-mail :

  1. Le contrôleur veut valider le composant, il appellera donc la directive interne pour obtenir l'élément d'entrée interne.
  2. La directive renvoie l'entrée au contrôleur.
  3. Le contrôleur peut vérifier l'entrée en fonction des validations qui lui sont liées.

J'ai essayé différentes approches, mais je ne parviens pas à atteindre l'objectif final.

Voici l'exemple avec lequel j'ai travaillé.

MODIFIER

Résolu : http://plnkr.co/edit/DMUVLifuWeGEuXOVfRwE?p=preview

Était-ce utile?

La solution

Je me demande légèrement si vous avez besoin de la directive comme d’une véritable boîte noire.Tout d'abord, vous auriez généralement besoin de messages de validation ou d'informations affichées à l'utilisateur sur les différents cas de données invalides, donc une simple valeur de retour vrai/faux de n'importe quel validateur ne suffit pas.Deuxièmement, vous recréez également une grande partie de ce qu'Angular vous offre déjà avec ngForm, ngModel, ngModelController et le input directive, en particulier la $setValidity fonction de ngModelController

Je mettrais chaque validateur dans sa propre directive qui requires ngModel:un pour le courrier électronique et un pour le mot de passe par exemple.Cependant, vous pouvez toujours transmettre des options à partir du contrôleur global, mais chaque directive est adaptée aux informations dont elle a besoin.Par exemple, un validationEmail La directive peut accepter un éventail d'e-mails existants utilisés :

<input validation-email validation-email-used="usedEmails" ng-model="data.email" type="text" placeholder="Email" name="email" ng-required />

usedEmails est un ensemble d'e-mails.La directive pourrait s’écrire ainsi :

app.directive('validationEmail', function() {
  return {
    require: 'ngModel',
    scope: {
      validationEmailUsed:'='
    },
    link: function(scope, element, attributes, ngModelController) {
      scope.$watch(function() {
         return ngModelController.$viewValue
       }, function(email) {
         // Test the email and call
         // ngModelController.$setValidity(...)
         // to set the validity of the email
      });
    }
  };
});

Vous pouvez voir cela en action dans un version modifiée de votre Plunker

Modifier:Si vous souhaitez intégrer la validation côté serveur, une fois que toute la validation côté client est passée des directives, vous pouvez le faire à partir de la fonction passée à ngSubmit Sur le formulaire:

<form name="myForm" ng-submit="submit()">

Ce qui peut être codé en utilisant le fait que le formulaire s'expose sur la portée, et tous ses ngModel contrôleurs (pour le même exemple, en utilisant un $timeout, plutôt que d'appeler $http ou un service),

$scope.submit = function() {
 $timeout(function() {
   $scope.myForm.username.$setValidity('available',false);
   $scope.myForm.email.$setValidity('emailFree',false);
  },500);
}

Un problème avec ceci est que vous souhaiterez peut-être alors marquer l'entrée comme valide une fois que l'utilisateur l'a modifiée.Vous pourriez créer un validOnChange directive, à utiliser comme :

<input ng-model="data.username" type="text" placeholder="Username" name="username" valid-on-change="available" ng-required />

et codé comme suit :

app.directive('validOnChange', function() {
  return {
    require: 'ngModel',
    scope: '',
    link: function(scope, element, attributes, ngModelController) {
      scope.$watch(function() {
        return ngModelController.$viewValue
      }, function() {
        ngModelController.$setValidity(attributes.validOnChange,true);
      });
    }
  }
});

Tu peux voir ça dans ce Plunker.

Un autre avantage général de travailler avec ngForm et ngModelController est qu'il ajoute de nombreuses classes au formulaire et à l'élément en fonction de l'état d'erreur/valide des entrées, et expose l'état d'erreur sur la portée, afin que vous puissiez afficher/masquer l'erreur. messages facilement en utilisant ngIf, Par exemple.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top