2016-08-26 2 views
0

wir individuellen Validierung-Methoden für benutzerdefinierte Formelemente über eine extra-Richtlinien registrieren:Eingang wird nie ng-invalid-Klasse von Angular

<ng-form name="validatorTestForm"> 
    <our-input-directive name="validatorTest" 
         ng-model="ourModel"/> 
    </our-input-directive> 
    <our-validator-directive name="validatorTest" 
          form="validatorTestForm" 
          ng-model="ourModel"> 
    </our-validator-directive> 
</ng-form> 

Es erhält alle Informationen über Attribute wissen, welchen Eingang in welcher Form zu validieren ist; wir verbinden es dann wie das durch die Richtlinie Einleitung: (abgespeckte Version)

registerValidator(ourModel.form, 'validatorTest'); 

function registerValidator(form, inputName) { 
    var validationModel = form[inputName]; 

    validationModel.$validators.testValidator = function (modelValue) { 
     // validate to true when there are more then two characters entered 
     return modelValue.length > 2; 
    }; 
} 

Die unsere eintritt Richtlinie ganz einfach:

angular.directive('ourInputDirective', function() { 
    return { 
     restrict: 'E', 
     template: '<input type="text" ng-model="model">', 
     scope: { 
      model: '=?ngModel' 
     } 
    } 
}); 

So laufen wir es, Angular hat seine Magie und fügt dem form-element und dem input-element tons css-classes hinzu und wenn wir etw. In die Eingabe wird die Validierung ordnungsgemäß ausgelöst. Das Formularelement erhält eine CSS-Klasse 'ng-gültig', wenn es gültig ist und 'ng-ungültig', wenn es nicht gültig ist.

Die Eingabe howewer, hat nur die Klasse 'ng-valid' und wird niemals ungültig!
Also warum ist das und wie kann ich es ändern, um die Modell-Änderungen an den Eingängen css-Klassen widerzuspiegeln?


Wir möchten die 'ng-invalid' Klasse verwenden, um den Stil der Eingabe zu ändern.

+0

Ich gehe davon aus, die Validierung ist nur ein Beispiel, wenn es nicht dann ist, können Sie nur eine normale Texteingabe verwenden und das Attribut minlength verwenden. – George

+0

Ja, wir möchten über diese Direktive alle Arten von benutzerdefinierten Validierungsmethoden hinzufügen können. – MaxBoehme

Antwort

1

Verwenden ng-Modell https://docs.angularjs.org/api/ng/directive/ngModel

ngModel ist verantwortlich für:

  • Bindung der Ansicht in das Modell, die von anderen Richtlinien wie Eingabe, TextArea- oder wählen Sie erfordern.
  • Bereitstellung von Validierungsverhalten (d. H. Erforderlich, Nummer, E-Mail, URL).
  • Behalten Sie den Status der Kontrolle (gültig/ungültig, schmutzig/unberührt, berührt/unberührt, Validierungsfehler).
  • Festlegen verwandter CSS-Klassen für das Element (ng-gültig, ng-ungültig, ng-schmutzig, ng-unberührt, ng-berührt, ng-unberührt, ng-leer, ng-nicht-leer) einschließlich Animationen.
  • Registrieren des Steuerelements mit seiner übergeordneten Form.

Hier ist ein worknig plnkr in der Art und Weise Sie es tun. https://plnkr.co/edit/yWlZln2TekdCAhrZ6iEG?p=preview

function customValidator() { 
    var directive = { 
     require: '^form', 
     link: link 
    }; 
    return directive; 

    function link(scope, element, attrs, formCtrl) { 
     modelCtrl = formCtrl[attrs['name']]; 
     modelCtrl.$validators.testValidator = function (modelValue, viewValue) { 
     var value = modelValue || viewValue; 
     if(modelCtrl.$isEmpty(value)){ 
      return false; 
     } 
     return value.length > 2; 
     }; 
    } 
} 
+0

Während ein guter Vorschlag, bitte erweitern Sie Ihre Antwort, sonst könnte dies ein Kommentar sein. – George

+0

Ich habe eine Reparatur gemacht. – krutkowski86

+0

@MaxBoehme Überprüfen Sie meine PLNKR über – krutkowski86

0

Wie krutkowski86 versuchen vorgeschlagen, ein ng-Modell Richtlinie anstelle der Art und Weise verwenden Sie es tun, ist ein Beispiel unter

<ng-form name="validatorTestForm"> 
    <input type="text" name="validatorTest" ng-model="MyVar" validator/> 
</ng-form> 


angular.module('yourModule').directive('validator', validator); 

function validator() { 
    var directive = { 
     require: 'ngModel', 
     link: link 
    }; 
    return directive; 

    function link(scope, element, attrs, ngModel) { 
     ngModel.$validators.testValidator = function (modelValue) { 
     // validate to true when there are more then two characters entered 
     return modelValue.length > 2; 
     }; 
    } 
} 

Bitte meine Plunker für ein Beispiel siehe https://plnkr.co/edit/mErINFdPt0odIOdu4Em2?p=preview

+0

Es scheint, dass die Lösung in der Tatsache liegen könnte, dass Sie das verlangen: 'ngModel' und ich nicht. Ohne es in Ihrem Beispiel zu verwenden, verhält es sich so falsch wie meins. – MaxBoehme

+0

Etwas richtig, ein anderes Element zu haben, um die Gültigkeit Ihrer Formulareingabe zu überprüfen, ist nicht die übliche Art, es zu tun, so wie in meinem Beispiel. – George

0

Nach einigen Tests haben wir das Problem herausgefunden:

Obwohl die 'unser-Validator- Direktive 'benutzte das ngModel der Eingabe, Es war nicht die Instanz des ngModel! Dies wurde durch einen isolierten Bereich auf die Direktive verursacht, die den Eingang enthält.(Was ich im Beispiel nicht hinzugefügt habe, weil ich es nie als Problem betrachtet habe ...) Daher sind Änderungen am ngModel der 'unserer-Validator-Direktive' nicht zu der ursprünglichen übergegangen.

ngModelCtrl = form[nameOfTheInput] 

Statt die erforderliche ngModel zu verwenden, die in die Validierer Richtlinie übergeben bekommen:

Sie haben wirklich mit dem Original verknüpft, was mit leicht achived.

[Ich habe das Beispiel bearbeiten. ]