2

J'ai une directive "EnsureUniqueValidator" pour vérifier l'unicité des valeurs dans la base de données. La fonction est générique. Il est appelé dans la page HTML de la manière suivante:

<input type="email" name="email" ng-model="userCtrl.user.email" 
required ensure-unique-validator /> 

Code de la directive:

app.directive('ensureUniqueValidator', [ 
     '$http', 
     function($http) { 
      return { 
       restrict : 'A', 
       require : 'ngModel', 
       link : function(scope, ele, attrs, c) { 

        c.$parsers.push(function(val) { 

         return $http.get(
           'MainServlet.do?method=is' + attrs.name 
             + 'unique&' + attrs.name + '=' 
             + val).then(
           function(result) { 
            console.log(result.data); 
            c.$setValidity('ensureUniqueValidator', 
              result.data); 
            return result.data;//returns true or false 
           }); 
        }); 
       } 
      } 
     } ]); 

Le problème est, le formulaire reste valable même si le serveur est revenu comme faux. On dirait que la fonction $ setValidity n'invalide pas le formulaire.

Est-ce que je fais quelque chose de mal ici? Merci d'avance.

+0

Voir https://docs.angularjs.org/guide/forms#custom-validation. Vous devriez utiliser 'c. $ AsyncValidators', pas' c. $ Parsers' – Phil

+0

Merci pour le lien. La directive est appelée correctement et la fonction setValidity est également appelée. Pourriez-vous s'il vous plaît préciser pourquoi le code ci-dessus ne fonctionne pas ?, J'avais essayé asyncValidators mais le résultat était le même. Je vais essayer avec le lien que vous avez fourni mais si vous pouvez me signaler ce qui ne va pas dans le code ci-dessus, ce serait très utile pour éclaircir mon doute. Merci encore. – JVM

+0

Jetez un oeil à l'exemple de code ('script.js') sous le lien * Custom Validators * ci-dessus. La directive 'username' est similaire à ce que vous voulez. Vous avez simplement besoin de retourner une promesse – Phil

Répondre

1

Cela devrait fonctionner (selon les docs de toute façon, je n'en ai pas encore écrit un).

La chose principale semble être que la promesse soit devrait détermination pour une valeur valide ou rejeter pour un un invalide.

// don't forget to inject the $q service 
c.$asyncValidators.ensureUniqueValidator = function(modelValue, viewValue) { 
    if (ctrl.$isEmpty(modelValue)) { 
     // consider empty model valid 
     return $q.when(); 
    } 

    var params = { 
     method: 'is' + attrs.name + 'unique' 
    }; 
    params[attrs.name] = modelValue; 

    return $http.get('MainServlet.do', { 
     params: params 
    }).then(function(response) { 
     if (!response.data) { 
      return $q.reject(); 
     } 
     return true; 
    }); 
}; 
+0

Salut Phil, ce code a fonctionné, j'accepte la réponse. Merci! ... J'ai d'abord essayé la validation du serveur sur l'événement "Blur". Je veux dire, le formulaire doit rester invalide jusqu'à ce que la valeur soit retournée comme unique == vrai du serveur. Cela évite les appels continus au serveur pendant que l'utilisateur tape sur le terrain (en cours). Pourriez-vous s'il vous plaît m'aider à réaliser la même chose? Merci! – JVM

+0

@JVM Toujours travailler sur la validation côté serveur décent sur me soumettre. Je ne suis pas un fan du style de validation continue que favorise Angular. Il y a quelques idées dans ce post ~ http://stackoverflow.com/questions/12864887/angularjs-integrating-with-server-side-validation – Phil

+1

J'ai utilisé "debounce" pour les champs que j'ai besoin de vérifier avec le serveur et cela m'a aidé. Il me laisse finir la frappe et fait un appel de serveur, fonctionnant semblable à l'événement de flou. ng-model-options = "{debounce: 500}" – JVM