1

Ich habe diese $parser, die die Anzahl der Zeichen begrenzt, die Benutzer eingegeben hat:Auslösung AngularJS ng-Modell Pipeline onBlur

var maxLength = attrs['limit'] ? parseInt(attrs['limit']) : 11; 

    function fromUser(inputText) { 
     if (inputText) { 
      if (inputText.length > maxLength) { 
       var limitedText = inputText.substr(0, maxLength); 
       ngModel.$setViewValue(limitedText); 
       ngModel.$render(); 
       return limitedText; 
      } 
     } 
     return inputText; 
    } 

    ngModel.$parsers.push(fromUser); 

Ich möchte diese Richtlinie über ein Eingabeelement verwenden, das ng-model-options="{updateOn: 'blur'}" hat, aber es gibt eine Problem, dass die ganze $parser Sache ausgeführt wird, nachdem Benutzer den Fokus des Eingabeelements verliert, möchte ich es als Benutzertypen in das Eingabefeld ausgeführt werden.

(function (angular) { 
 
    "use strict"; 
 
    angular.module('app', []) 
 
    .controller("MainController", function($scope) { 
 
     $scope.name = "Boom !"; 
 
     $scope.name2 = "asdf"; 
 
    }).directive('limitCharacters', limitCharactersDirective); 
 

 
    function limitCharactersDirective() { 
 
     return { 
 
      restrict: "A", 
 
      require: 'ngModel', 
 
      link: linkFn 
 
     }; 
 

 
     function linkFn(scope, elem, attrs, ngModel) { 
 
      var maxLength = attrs['limit'] ? parseInt(attrs['limit']) : 11; 
 

 
      function fromUser(inputText) { 
 
       if(inputText) { 
 
        if (inputText.length > maxLength) { 
 
         var limitedText = inputText.substr(0, maxLength); 
 
         ngModel.$setViewValue(limitedText); 
 
         ngModel.$render(); 
 
         return limitedText; 
 
        } 
 
       } 
 
       return inputText; 
 
      } 
 

 
      ngModel.$parsers.push(fromUser); 
 
     } 
 
    } 
 

 
})(angular);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script> 
 

 
<div ng-app="app"> 
 
    without ng-model-options: <input type="text" ng-model="name" limit-characters limit="7" /> 
 
    
 
    <br> 
 
    with ng-model-options <input type="text" ng-model="name2" ng-model-options="{updateOn: 'blur'}" limit-characters limit="7" /> 
 
</div>

Antwort

1

Wenn ein Benutzer in der Eingabe einen Wert eingibt $setViewValue wird intern genannt. Wie in angular docs angegeben ist, was $setViewValue tut:

Wenn $ setViewValue aufgerufen wird, wird der neue Wert für durch die $ Parser und $ Validatoren Pipelines zu begehen statt. Wenn dort keine speziellen ngModelOptions angegeben sind, wird der gestaffelte Wert direkt zur Verarbeitung über die $ parsers-Pipeline gesendet. Danach werden die $ validators und $ asyncValidators aufgerufen und der Wert an $ modelValue übergeben. Schließlich wird der Wert im Attribut ng-model auf den angegebenen Ausdruck gesetzt, und alle registrierten Änderungslistener werden in die Liste $ viewChangeListeners aufgerufen.

Falls die ngModelOptions Richtlinie mit updateOn verwendet und die Standard-Trigger nicht aufgeführt ist, all diese Aktionen bleiben , bis eine der updateOn Ereignisse anhängig ist auf dem DOM-Element ausgelöst wird.

Was es bedeutet, dass $parsers nur bei Änderung tatsächlichen Modell verwendet werden, begehen (die in Ihrem Fall auf Blur passiert).

Die einfachste Lösung für Ihr Problem wäre $parsers nicht zu verwenden, um die Zeichen zu begrenzen. Überprüfen Sie andere Lösungen in diesem question.

die meisten upvoted Antwort Verwenden Sie Ihre Richtlinie ändern können, um es so aussehen zu lassen:

function limitCharactersDirective() { 
    return { 
     restrict: "A", 
     require: 'ngModel', 
     link: linkFn 
    }; 

    function linkFn(scope, elem, attrs, ngModel) { 
     var maxLength = attrs['limit'] ? parseInt(attrs['limit']) : 11; 
     angular.element(elem).on("keypress", function(e) { 
      if (this.value.length == maxLength) e.preventDefault(); 
     }); 
    } 
} 

Check this JSFiddle für ein funktionierendes Beispiel.

+0

sehr gut geschrieben, aber ich habe ein Problem mit der neuen Richtlinie, wenn Benutzer kopieren und in die Richtlinie einfügen, es wird es nicht bemerken. irgendeine Idee? – Rachmaninoff