2014-11-17 7 views
16

Ich habe einen Asynchron-Validator:Betrachten wir eine Form ungültig, während asynchroner Validator Versprechen anhängig

app.directive('validateBar', ['$http', function($http) { 
    function link($scope, $element, $attrs, ngModel) { 
     ngModel.$asyncValidators.myValidator = function(value) { 
      return $http.get('/endpoint/' + value); 
     }; 
    } 
    return { 
     require: 'ngModel', 
     link: link 
    }; 
}]); 

Formularvorlage:

<form name="myForm" ng-submit="foo.$valid && saveForm()"> 
    <input name="bar" ng-model="bar" data-validate-bar> 
    <p ng-show="myForm.bar.$error.myValidator">Your bar is wrong</p> 
    <button disabled="myForm.$invalid"> 
</form> 

Problem: Ich möchte meine Begleit Form ungültig sein, während die myValidator Versprechen steht aus.

Ich kenne zwei Möglichkeiten, um ein Formular ungültig zu machen, während Async-Validatoren ausstehen, aber sie sind sowohl ausführlich und/oder hacky.

// Workaround 1: Mark another validator as invalid while the validator promise is pending. 
// I cannot mark 'myValidator' as invalid, gets set to valid immediately by Angular. 
app.directive('validateSomething', ['$http', function($http) { 
    function link($scope, $element, $attrs, ngModel) { 
     ngModel.$setValidity('async', false); 
     ngModel.$asyncValidators.myValidator = function(value) { 
      return $http.get('/endpoint/' + value).then(function() { 
       ngModel.$setValidity('async', true); 
      }); 
     }; 
    } 
    return { 
     require: 'ngModel', 
     link: link 
    }; 
}]); 

<!-- Workaround 2: Prevent submitting through the UI --> 
<form name="myForm" ng-submit="myForm.$valid && !myForm.$pending && saveForm()"> 
    <input name="bar" ng-model="bar" data-validate-bar> 
    <p ng-show="myForm.bar.$error.myValidator">Your bar is wrong</p> 
    <button disabled="myForm.$invalid || myForm.$pending"> 
</form> 

Ich mag Abhilfe 1 nicht, weil ich einen anderen Validator markieren (async) als ungültig, welche Effekte unbeabsichtigte Neben haben kann, und ich weiß nicht, wie Abhilfe 2, weil ich kann nicht länger vertrauen form.$valid von selbst.

Kennt jemand eine saubere Lösung?

+0

Ich bin mir nicht sicher, wie ich deine Frage am besten beantworten soll, aber ich möchte nur meinen Ansatz teilen, falls es hilft. Demo hier: http://m59peacemaker.github.io/angular-pmkr-components/#/validate-custom und Direktive hier: https://github.com/m59peacemaker/angular-pmkr-components/tree/master/src/ directions/validateCustom – m59

+0

Ich denke, Sie verwenden eine ähnliche Lösung wie die Problemumgehung 2, da Sie in Ihrer Ansicht nach ausstehend suchen. – Blaise

+0

Ich verstehe, warum Sie nicht die Formularvalidierung des Frameworks hacken wollen. Ich denke, Sie versuchen zu sehr, die Gültigkeit des Formulars für mehrere Zwecke zu verwenden. Sie sollten zwei verschiedene Formen von valid haben: Formular gültig nach UI-Regeln und Validierung der Async-Daten gültig, die ein Scope-Variablen-Flag sein sollte. Die nächste Frage ist, welchen UI-Effekt du mit 'AsyncFlag = invalid' begleiten willst. Wenn keins vorhanden ist und Sie es nur zum Einreichen von Zuwendungen verwenden möchten, können Sie die Übermittlungsschaltfläche einfach deaktivieren, während Ihr Async-Validiererversprechen aufgelöst wird. –

Antwort

24

Sie können $pending verwenden, um zu testen, ob ein Async-Validator für das gesamte Formular oder ein bestimmtes Eingabeelement aussteht. Ich fügte auch einen Test auf $pristine hinzu, um Fehlermeldungen zu verstecken, wenn die Seite lädt und ng-disabled anstelle von disabled auf der button verwendete.

<form name="myForm" ng-submit="foo.$valid && saveForm()"> 
    <input name="bar" ng-model="bar" data-validate-bar> 
    <div ng-show="! myForm.$pristine"> 
     <p ng-show="myForm.bar.$pending.myValidator || myForm.bar.$error.myValidator">Your bar is wrong</p> 
    </div> 
    <button ng-disabled="myForm.$invalid || myForm.$pending">Do smth</button> 
</form>