2016-05-04 22 views
0

Ich benutze UI-Bootstrap Datepicker Eingabe mit AngularJS. Es verfügt über einen ngModel und eine validatioon Methode ngBlur Ereignis gebunden:ngModel aktualisiert nach ngBlur

<input id="startDate" type="text" ng-model="myCtrl.startDate" ng-blur="myCtrl.validateDate()"/> 

Das Validierungsverfahren prüft das ngModel nach Satz von Regeln in der Steuerung und Warnungen, wenn nötig. Hier ist der zugehörige Teil der Steuerung:

var vm = this; 
vm.startDate = new Date(); 
vm.minStartDate = new Date(2000,1,1); 
vm.validateDate = function(){ 
    if(vm.startDate < vm.minStartDate) 
     alert("Start date can't be earliar than 2000"); 
} 

Das Problem ist, dass die Validierungsverfahren laufen vor der Aktualisierung des Modells. Das Beispielszenario ist wie folgt:

Die Regel: startDate darf nicht vor dem Jahr liegen. Wenn die Seite geladen wird, wird der startDate-Wert anfänglich auf "Heute" gesetzt. Der Benutzer wählt 31.12.1999 aus dem Kalender aus, die ngBlur-Methode wird aufgerufen. NgModel wurde jedoch noch nicht aktualisiert. Somit überprüft die Validierung den heutigen Wert und sagt ok. Eigentlich hätte es ngModels Wert mit 31.12.1999 überprüft werden sollen. Der Wert ändert sich gleichzeitig in der Eingabeansicht, aber im Hintergrund wird er eingestellt, nachdem die Weichzeichnungsmethode ausgelöst wurde. Soweit ich weiß, dient normalerweise die Zweiwege-Bindung in AngularJS diesem Zweck, aber die ngBlur muss eine Ausnahme darstellen.

Ich habe viele Dinge wie versucht;

  • Hinzufügen ng-model-Optionen auf die Komponente:

    ng-model-options="{ updateOn: 'blur' }"

  • Verwendung von Pre- und Post-Verknüpfung durch das Eingangselement modifizierende

  • Verwendung ng Änderungs anstelle von ng-Unschärfe

Allerdings funktioniert keiner der oben genannten, und noch NG-Blur läuft vor dem Das Modell wurde aktualisiert.

Antwort

0

Ich habe die Lösung gefunden, indem ich die Werte innerhalb der Steuerung manuell aktualisiere. Offensichtlich aktualisiert AngularJS das Modell nicht mit dem Wert innerhalb des HMTL-Elements, bis das Blur-Ereignis ausgelöst wird. Also, es ist besser, eine Methode zu schreiben, um es zu aktualisieren.

kann ich den Wert innerhalb des Elements zugreifen, wie folgt:

vm.startDate = angular.element('#startDate').val(); 

Dann kann ich diese wickeln mit einer Methode:

vm.updateModels() = function(){ 
    vm.startDate = angular.element('#startDate').val(); 
} 

Schließlich habe ich dies nur auf den Ruf ersten meiner Blur-Event:

vm.validateDate = function(){ 
    //Update first 
    vm.updateModels(); 
    //Then validate 
    if(vm.startDate < vm.minStartDate) 
     alert("Start date can't be earliar than 2000"); 
} 

Ta tammm, jetzt kann ich die Update-Werte validieren!

0

Ein einfacher Weg, um sicherzustellen, dass Ihre Validierung nur ausgelöst wird, sobald der Wert aktualisiert wird, besteht darin, sie auf einer ng-Änderung anstelle von ng-blur aufzurufen. Auf diese Weise können Sie sicher sein, dass der Controller nur dann auswertet, wenn der ng-Modellwert aktualisiert wurde.

0

Versuchen Sie besitzen benutzerdefinierten Validator (Richtlinie) dieses Beispiel

app.directive('integer', function() { 
    return { 
    require: 'ngModel', 
    link: function(scope, elm, attrs, ctrl) { 
     ctrl.$validators.integer = function(modelValue, viewValue) { 
     if (ctrl.$isEmpty(modelValue)) { 
      // consider empty models to be valid 
      return true; 
     } 

     if (INTEGER_REGEXP.test(viewValue)) { 
      // it is valid 
      return true; 
     } 

     // it is invalid 
     return false; 
     }; 
    } 
    }; 
}); 

prüfen https://plnkr.co/edit/SZoBKakhzIq5wRoCvEyG?p=preview

zu bauen