2013-06-09 25 views
9

Ich habe eine Validierungsanweisung namens valid-number, die verwendet wird, um die Gültigkeit eines Formulars mit $ setValidity zu setzen - das funktioniert für alle Textwerte, die ich in das Eingabefeld eingeben, auf die die Direktive angewendet wurde als ein Attribut.Angularjs anfängliche Formularvalidierung mit Direktiven

Die HTML ist

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

Die Richtlinie als

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

jedoch folgen, ich möchte auch, dass die Validierung ausgelöst werden und die CSS auf einen ungültigen clsss gesetzt, wenn der Wert der Eingangs Box wird initialisiert, wenn die Seite zum ersten Mal geladen wird, ist ungültig, zB wenn ich $scope.amount = 'not a number' setze, würde ich erwarten, dass das Eingabefeld die Direktive hat, aber keine Freude. Damit not a number als ungültig markiert werden kann, muss ich den Inhalt der Eingabe ändern, was die Anweisung auslöst.

Wie kann ich sicherstellen, dass die Richtlinie gilt für was auch immer die <input> initialisiert wird?

Ein vollständiges Codebeispiel ist hier;

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

Antwort

16

$parsers Array enthält eine Liste von Funktionen, die das Modell erhält auf den Wert angewendet wird Aus der Ansicht (welcher Benutzer eingibt) und dem Array $formatters enthält die Liste der Funktionen, die auf den Modellwert angewendet werden, bevor er in der Ansicht angezeigt wird.

In Ihrer Richtlinie Sie richtig verwendet, um die $parsers Array, aber Sie müssen auch die $formatters Array hinzufügen, wenn Sie den Anfangswert soll validiert werden:

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

Das hat super funktioniert. – GrahamB

+1

Wirklich toller Beitrag und es hebt wichtige Details wie $ Parser und $ Formatierer hervor, die in der Dokumentation schwer zu finden sind. – Tobias

+0

Gerade in komplexe Cross-Field-Validierungen und diesen Beitrag gerettet den Tag - oder verwandelte sich einen Tag in ein paar Minuten heh! – bchesley

1

Sie können einfach Ihre Verifikationsfunktion während der Verknüpfungsphase nennen, wie in diesem 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

Nach (> =) eckige Version 1.3.1 wurde veröffentlicht, Sie könnten dieses Verhalten mit ein wenig korrektem Weg implementieren, indem Sie dem Typ der Winkelvalidierung folgen (zB required, maxlength).

In diesem Fall haben Sie Ihre Validator als Eigentum von $validators Array anzuhängen, und es gibt keine Notwendigkeit, in $parsers oder $formatters mehr:

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>

Verwandte Themen