2013-06-09 15 views
9

Ho una direttiva di convalida denominata valid-number che viene utilizzata per impostare la validità di un modulo utilizzando $ setValidity - questo funziona correttamente per tutti i valori di testo che digito nella casella di input a cui è applicata la direttiva come un attributo.Convalida modulo iniziale di Angularjs con le direttive

L'HTML è

<form name="numberForm"> 
<input name="amount" type="text" ng-model="amount" required valid-number /></form> 

La direttiva è la seguente

angular.module('test',[]).directive('validNumber',function(){ 
      return{ 
       require: "ngModel", 
       link: function(scope, elm, attrs, ctrl){ 

        var regex=/\d/; 
        ctrl.$parsers.unshift(function(viewValue){ 
         var floatValue = parseFloat(viewValue); 

         if(regex.test(viewValue)){ 
          ctrl.$setValidity('validNumber',true); 
         } 
         else{ 
          ctrl.$setValidity('validNumber',false); 
         } 
         return viewValue; 
        }); 
       } 
      }; 
     }); 

Tuttavia, vorrei anche come la convalida da attivare e impostare il css per un clsss valida se il valore di ingresso la casella è inizializzata quando la pagina è stata caricata per la prima volta non è valida, ad es. se ho impostato $scope.amount = 'not a number', mi sarei aspettato che la casella di input avesse la direttiva applicata, ma nessuna gioia. Affinché lo not a number sia evidenziato come non valido, devo apportare una modifica al contenuto dell'ingresso, che attiva la direttiva.

Come posso garantire che la direttiva si applichi a qualsiasi sia <input> inizializzato con?

Un esempio di codice completo è qui;

http://jsfiddle.net/JW43C/5/

risposta

16

$parsers matrice contiene un elenco di funzioni che verranno applicate al valore che il modello riceve dalla vista (in cui l'utente digita) e l'array $formatters contiene l'elenco di funzioni che vengono applicate al valore del modello prima che venga visualizzato nella vista.

Nella direttiva si è utilizzato correttamente la matrice $parsers, ma è anche necessario aggiungere la matrice $formatters se si desidera che il valore iniziale da convalidare:

angular.module('test',[]).directive('validNumber',function(){ 
    return{ 
    require: "ngModel", 
    link: function(scope, elm, attrs, ctrl){ 
     var regex = /^\d$/; 
     var validator = function(value){ 
     ctrl.$setValidity('validNumber', regex.test(value)); 
     return value; 
     }; 

     ctrl.$parsers.unshift(validator); 
     ctrl.$formatters.unshift(validator); 
    } 
    }; 
}); 

Demo plunker

+0

questo ha funzionato grande. – GrahamB

+1

Davvero un ottimo post e mette in evidenza dettagli importanti come $ parser e $ formattatori che sono difficili da trovare nella documentazione. – Tobias

+0

Basta entrare in convalide complesse convalide e questo post ha salvato il giorno - o ha trasformato un giorno in pochi minuti eh! – bchesley

1

Si può semplicemente chiamare la funzione di verifica durante la fase di collegamento, come in questo fiddle:

link: function(scope, elm, attrs, ctrl) {      
    var regex=/\d/; 
    var verificationFunction = function(viewValue) { 
     var floatValue = parseFloat(viewValue); 

     if(regex.test(viewValue)) { 
      ctrl.$setValidity('validNumber',true); 
      return viewValue; 
     } 
     else { 
      ctrl.$setValidity('validNumber',false); 
      return undefined; 
     } 
    }; 

    ctrl.$parsers.unshift(verificationFunction); 
    verificationFunction(); 
} 
0

Dopo (> =) è stata rilasciata la versione angolare 1.3.1, è possibile implementare tale comportamento con un po 'di corretto modo, seguendo lo stile delle direttive di convalida angolare (ad es. required, maxlength).

In questo caso si deve accodare il tuo validatore di propietà della $validators matrice e non ci sono necessità in $parsers o $formatters più:

var app = angular.module('test', []); 
 

 
app 
 
    .directive('validNumber', function() { 
 
    return { 
 
     require: "ngModel", 
 
     link: function(scope, elm, attrs, ctrl) { 
 
     var regex = /^\d+$/; 
 

 
     ctrl.$validators['validNumber'] = function(modelValue, viewValue) { 
 
      return regex.test(viewValue); 
 
     }; 
 
     } 
 
    }; 
 
    }); 
 

 
app.controller('NumberCtrl', NumberCtrl); 
 

 
function NumberCtrl($scope) { 
 
    $scope.amount = '5z'; 
 
};
input.ng-invalid { 
 
    background-color: #FA787E; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.min.js"></script> 
 

 
<div ng-app="test"> 
 
    <div ng-controller="NumberCtrl"> 
 

 
    <div ng-form name="numberForm"> 
 
     <input name="amount" 
 
      type="text" 
 
      ng-model="amount" 
 
      required 
 
      valid-number /> 
 
     
 
     <span ng-show="numberForm.amount.$error.validNumber"> 
 
     Doesn't look like an integer 
 
     </span> 
 
    </div>   
 
    </div> 
 
</div>

Problemi correlati