2016-07-15 11 views
0

Ich habe einige Richtlinien erstellt, die mir helfen in Form Eingabe Gültigkeit zu überprüfen, die mehr oder weniger wie folgt aussehen:Eingabevalidierungsfehler von innen Richtlinie abrufen

app.directive("initialDate", function(){ 
    return{ 
     require: '?ngModel', 
     restrict:"A", 
     link:function(scope, element, attrs, ngModel){ 
      scope.$watch(attrs.ngModel, function() { 
       validate(); 
      }); 
      attrs.$observe('initialDate', function() { 
       validate(); 
      }); 
      var validate = function() { 
       var date = Date.parse(ngModel.$viewValue); 
       var initialDate = Date.parse(attrs.initialDate); 
       ngModel.$setValidity('initial-date', date >= initialDate); 
      } 
     } 
    } 
}); 

Nun, ich möchte benutzerdefinierte Nachrichten auf Eingaben hinzufügen, selects, etc .., die die Validierung nicht bestehen, aber ich möchte nicht eins nach dem anderen hinzufügen, indem ich einen Bereich oder etwas mit ng-if hinzufüge (das ist eine Menge Arbeit, die ich vermeiden will).

Mein erster Versuch war, eine Richtlinie wie diese zu erstellen:

app.directive("ngInvalid", function(){ 
    restrict:"C", 
    ... 
}); 

aber das nicht funktioniert, so jetzt ich versuche diese

app.directive("input", function(){ 
    return { 
     require:"?ngModel", 
     link:function(scope, element, attrs, ctrl){ 
      scope.$watch(function() { 
       return element.attr('class'); 
      }, function(newVal, oldVal){ 
       if (newVal == oldVal) return;  
       if (element.hasClass("ng-invalid")){ 
        element.parent().append("<span class = 'error' style='color:red'>There was an error</span>"); 
       }else{ 
        element.parent().find(".error").remove(); 
       } 
      }); 
     } 
    } 
}); 

Also, diese funktioniert (mehr oder weniger, es braucht mehr Arbeit, hehe), aber ich muss einen für selects, textareas, etc .. erstellen und einige Prüfungen für jede Art von Fehler machen, wenn ich benutzerdefinierte Nachrichten anzeigen möchte.

Außerdem sieht es wirklich schmutzig für mich aus. Ich glaube wirklich, dass es muss etwas sein, das ich in der Richtlinie tun könnte, die mehr sah wie folgt aus:

... 
link:function(scope, element, attrs, ctrl){ /***element is the input or select or textarea... ***/ 
    if (!element.$isValid){ 
     switch (element.$validationErrors[0]){ 
      case "emailValidation": element.parent().append("<span class = 'error' style='color:red'>Email format not correct</span>"); break; 
      case "initialDate": element.parent().append("<span class = 'error' style='color:red'>Date cannot be previous to {{initialDate}}</span>"); break; 
      case "pattern": element.parent().append("<span class = 'error' style='color:red'>Format incorrect</span>"); break; 
     } 

    } 
} 
... 

Ich habe in der Dokumentation und Navigation einige Fragen, suchen aber vor allem habe ich Lösungen gefunden, die verwenden, erfordern der Formular-Controller, und das möchte ich vermeiden.

Gibt es einige Methoden, die es mir ermöglichen, den Fehler von einer Eingabe abzurufen?

EDIT

Um deutlich zu machen, sagen wir mal, dass die Eingänge in einem Formular-Tag nicht eingewickelt werden, sondern ein div oder sonst etwas. Wie würde ich auf jeden Fehler innerhalb der Eingabedirektive zugreifen?

+2

Schauen Sie sich die NG-Nachrichten an: – dewd

+0

Scheint gut, löst aber nicht die zwei Dinge, die ich erreichen möchte: nicht abhängig von der Verwendung des Formulars und dem Erstellen einer Komponente für jeden Eingang, wenn ich einen Anzeigefehler für jedes Feld anzeigen möchte . – sergio0983

Antwort

0

Kurzantwort

Nein, nicht möglich, es ist ohne Form Controller Gültigkeitsprüfungen zuzugreifen.

Umgehung

Ich benutzte Eingangs Richtlinie zu erreichen, was ich wollte, aber Es spielt keine scheint zu elegant mir (Id wirklich eine Richtlinie verwenden möchten, die Textbereiche und wählt beeinflusst, ohne dass hinzufügen my-custom-Richtlinie zu jedem Feld I)

(function(){ 
    var lang = navigator.language.substr(0,2) || navigator.userLanguage.substr(0,2); 

    const E_UNKNOWN = 0, 
    E_REQUIRED = 1, 
    E_NAN = 2, 
    E_MIN = 3, 
    E_MAX = 4, 
    E_EMAIL = 5, 
    E_MINLEN = 6, 
    E_MAXLEN = 7, 
    E_PATTERN = 8, 
    E_BLACKLIST = 9, 
    E_EQUAL = 10; 
    E_INITIALDATE = 11; 

    const ERR_MESSAGES = [ 
     {'es':'Error desconocido', 'en':'Unknown Error'}, 
     {'es':'Este campo es obligatorio', 'en':'This field is mandatory'}, 
     {'es':'Este campo debe ser numérico', 'en':'This field should be numeric'}, 
     {'es':'El valor es inferior al mínimo', 'en':'Value is lower than the minimum'}, 
     {'es':'El valor es superior al máximo', 'en':'Value is higher than the maximum'}, 
     {'es':'El formato de email no es válido', 'en':'Email format incorrect'}, 
     {'es':'No cumple longitud mínima', 'en':'Minimum length not matched'}, 
     {'es':'No cumple longitud máxima', 'en':'Maximum length not matched'}, 
     {'es':'El formato no es válido', 'en':'Format incorrect'}, 
     {'es':'Este valor no está permitido', 'en':'This value is not allowed'}, 
     {'es':'Los campos no coinciden', 'en':'Fields doesn´t match'}, 
     {'es':'La fecha es anterior a la fecha inicial', 'en':'This date is previous to the initial date'}, 
    ]; 

    var lang = navigator.language.substr(0,2) || navigator.userLanguage.substr(0,2); 

    app.directive("input", function(){ 
     return { 
      scope:{}, 
      link:function(scope, element, attrs, ctrl, ngModel){ 
       scope.blurred = false; 
       element[0].addEventListener("blur", function(){ 
        scope.blurred = true; 
        element.parent().find(".error").remove(); 
        checkValidity(); 
       }); 

       var checkValidity = function(){ 
        var classList = element.attr('class'); 
        if (!classList) return; 
        var matches = classList.match(/ng-invalid-(.*?)(\s|$)/); 
        if (matches == null) return; 
        if (!(1 in matches)) return; 

        var $err = matches[1]; 
        var $errMessage = ""; 

        switch($err){ 
         case "required": $errMessage = ERR_MESSAGES[E_REQUIRED][lang]; break; 
         case "number": $errMessage = ERR_MESSAGES[E_NAN][lang]; break; 
         case "min": $errMessage = ERR_MESSAGES[E_MIN][lang]; break; 
         case "max": $errMessage = ERR_MESSAGES[E_MAX][lang]; break; 
         case "email": $errMessage = ERR_MESSAGES[E_EMAIL][lang]; break; 
         case "minlength": $errMessage = ERR_MESSAGES[E_MINLEN][lang]; break; 
         case "maxlength": $errMessage = ERR_MESSAGES[E_MAXLEN][lang]; break; 
         case "pattern": $errMessage = ERR_MESSAGES[E_PATTERN][lang]; break; 
         case "blacklist": $errMessage = ERR_MESSAGES[E_BLACKLIST][lang]; break; 
         case "equals": $errMessage = ERR_MESSAGES[E_EQUAL][lang]; break; 
         case "initial-date": $errMessage = ERR_MESSAGES[E_INITIALDATE][lang]; break; 
         default: $errMessage = ERR_MESSAGES[E_UNKNOWN][lang]; break; 
        } 

        if (element.hasClass("ng-invalid")){ 
         element.parent().append("<span class = 'error'>"+$errMessage+"</span>"); 
        } 
       } 
      } 
     } 
    }); 
})(); 

Hier ist ein Link zu einem Arbeits codepen validieren möchten: http://codepen.io/sergio0983/pen/AXxNpN?editors=1111

Aus irgendeinem Grund, In Codepen wird der Fehler nicht entfernt, wenn ich den $ -Selektor nicht über das Winkelelement verwende()

0

Der vorherige Ansatz, den ich gepostet habe, hatte einige Probleme. Die Überwachung der Klasse funktionierte nicht wie erwartet, sie wurde nicht ausgelöst, als sich die Klasse tatsächlich änderte, aber als das nächste Eingabe-Zeichen eingegeben wurde. Der erforderliche Fehler trat beispielsweise auf, wenn Sie nach dem Leeren ein neues Zeichen in die Eingabe eingefügt haben und das Protokoll in der Konsole und die Klasse im Inspector anders waren (vielleicht ein eckiger Fehler ??).

Wie auch immer, habe ich gefunden, was ich denke, eine bessere Lösung ist: Oh, und Es ist tatsächlich möglich, die Gültigkeitsprüfungen zuzugreifen, wenn die Steuerung nicht in einem Formular-Tag

Das ist die gewickelte Code (I Artikel nicht noch eine Unschärfe Prüfung hinzufügen, sollten aber leicht)

var errMsgDirective = function(){ 
    return{ 
     restrict:"E", 
     require:"?ngModel", 
     link:function(scope, element, attrs, ctrl, ngModel){ 
      if (!attrs.ngModel) return; 

      var lang = navigator.language.substr(0,2) || navigator.userLanguage.substr(0,2); 
      const E_UNKNOWN = 0, E_REQUIRED = 1, E_NAN = 2, E_MIN = 3, E_MAX = 4, E_EMAIL = 5, E_MINLEN = 6, E_MAXLEN = 7, E_PATTERN = 8, E_BLACKLIST = 9, E_EQUAL = 10; E_INITIALDATE = 11;  
      const ERR_MESSAGES = [ 
       {'es':'Error desconocido', 'en':'Unknown Error'}, 
       {'es':'Este campo es obligatorio', 'en':'This field is mandatory'}, 
       {'es':'Este campo debe ser numérico', 'en':'This field should be numeric'}, 
       {'es':'El valor es inferior al mínimo', 'en':'Value is lower than the minimum'}, 
       {'es':'El valor es superior al máximo', 'en':'Value is higher than the maximum'}, 
       {'es':'El formato de email no es válido', 'en':'Email format incorrect'}, 
       {'es':'No cumple longitud mínima', 'en':'Minimum length not matched'}, 
       {'es':'No cumple longitud máxima', 'en':'Maximum length not matched'}, 
       {'es':'El formato no es válido', 'en':'Format incorrect'}, 
       {'es':'Este valor no está permitido', 'en':'This value is not allowed'}, 
       {'es':'Los campos no coinciden', 'en':'Fields doesn´t match'}, 
       {'es':'La fecha es anterior a la fecha inicial', 'en':'This date is previous to the initial date'}, 
      ]; 
      var checkValidity = function(){ 
       if (!ctrl.$touched) return; 


       var errors = []; 
       for (var i in ctrl.$error){ 
        if (ctrl.$error[i] == false) continue;   
        switch (i){ 
         case "required": errors.push(ERR_MESSAGES[E_REQUIRED][lang]); break; 
         case "number": errors.push(ERR_MESSAGES[E_NAN][lang]); break; 
         case "min": errors.push(ERR_MESSAGES[E_MIN][lang]); break; 
         case "max": errors.push(ERR_MESSAGES[E_MAX][lang]); break; 
         case "email": errors.push(ERR_MESSAGES[E_EMAIL][lang]); break; 
         case "minlength": errors.push(ERR_MESSAGES[E_MINLEN][lang]); break; 
         case "maxlength": errors.push(ERR_MESSAGES[E_MAXLEN][lang]); break; 
         case "pattern": errors.push(ERR_MESSAGES[E_PATTERN][lang]); break; 
         case "blacklist": errors.push(ERR_MESSAGES[E_BLACKLIST][lang]); break; 
         case "equals": errors.push(ERR_MESSAGES[E_EQUAL][lang]); break; 
         case "initial-date": errors.push(ERR_MESSAGES[E_INITIALDATE][lang]); break; 
         default: errors.push(ERR_MESSAGES[E_UNKNOWN][lang]); break; 
        } 
       } 

       element.parent().find(".error").remove(); 
       if (errors.length == 0){ 

       }else{ 
        $errMessage = errors.join("; "); 
        element.parent().append("<span class = 'error'>"+$errMessage+"</span>"); 
       } 
      } 

      scope.$watch(function(){ 
       return JSON.stringify(ctrl.$error); 
      }, function(){ 
       checkValidity(); 
      }); 

      scope.$watch(function(){ 
       return ctrl.$touched; 
      }, function(){ 
       checkValidity(); 
      }) 
     } 
    } 
} 

app.directive("input", errMsgDirective); 
app.directive("textarea", errMsgDirective); 
app.directive("select", errMsgDirective); 

Es gibt einige Dinge, die ich darauf hinweisen möchte:

ersten: ich alle Fehler in Bezug auf jede Sonde in der Zugriff auf Richtlinie mit ctr l. $ error (um Gottes willen, warum gab es nicht eine einzige Antwort in allen Stack-Überlauf, die besagt, dass Sie auf Kontrollfehler mit zugreifen können. $ error ?? ¬¬)

zweiten: Ich hatte eine echte harte Zeit eine Uhr setzen, die gearbeitet: Ich habe versucht, alle folgenden:

scope.$watch(attrs.ngModel, function(){...}) //This one did not work because the model doesn´t change when the validity checks are not met 
scope.$watch(ctrl.$valid, function(){...}) //Never fired 
scope.$watch(ctrl.$invalid, function(){...}) //Never fired 
scope.$watch(ctrl.$error, function(){...}) //Never fired 
scope.$watch(function(){ return ctrl.$error }, function(){...}) //Never fired 
scope.$watch(function(){ return JSON.stringify(ctrl.$error) }, function(){...}) //BINGO!!! 

Hier können Sie sehen, es funktioniert:

http://codepen.io/sergio0983/pen/ZOvPvW?editors=1011

Verwandte Themen