2014-11-17 9 views
16

Ho un validatore asincrona: templateconsideri un form non valido, mentre le promesse asincrono validatore sono pendenti

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 
    }; 
}]); 

Forma:

<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> 

Problema: voglio che il mio modulo di accompagnamento da invalido mentre il myValidator promessa È in sospeso.

Conosco due metodi per invalidare un modulo mentre i validatori asincroni sono in sospeso, ma sono sia prolissi che/o 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> 

non mi piace soluzione 1 perché ho marchio altro validatore (async) come non valido, che può avere effetti collaterali indesiderati, e non mi piace soluzione 2 perché posso no più a lungo si fida di form.$valid da solo.

Qualcuno sa una soluzione pulita?

+0

Non sono sicuro di come rispondere al meglio alla tua domanda, ma voglio solo condividere il mio approccio nel caso in cui sia d'aiuto. Demo qui: http://m59peacemaker.github.io/angular-pmkr-components/#/validate-custom e direttiva qui: https://github.com/m59peacemaker/angular-pmkr-components/tree/master/src/ direttive/validateCustom – m59

+0

Penso che tu stia utilizzando una soluzione simile alla soluzione alternativa 2, poiché stai controllando la presenza di sospensioni nella tua vista. – Blaise

+0

Capisco perché non si vuole hackerare la convalida del modulo. Penso che tu stia cercando di usare Form Validity per diversi scopi. Dovresti avere 2 diverse forme di valid: Form Valid by UI rules, e Async validation data valid che dovrebbe essere un flag di scope scope. La prossima domanda è quale influenza dell'interfaccia utente vuoi accompagnare 'AsyncFlag = invalid'. Se nessuno, e lo vuoi solo per l'indennità di invio, puoi semplicemente disabilitare il pulsante di invio mentre la promessa del validatore asincrono è stata risolta. –

risposta

24

È possibile utilizzare $pending per verificare se un validatore asincrono è in sospeso sull'intero modulo o su un elemento di input specifico. Ho anche aggiunto un test su $pristine per nascondere i messaggi di errore quando la pagina viene caricata e utilizzata ng-disabled anziché disabled su button.

<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> 
Problemi correlati