2015-02-23 4 views
29

Ich möchte ein Äquivalent von ng-change für das gesamte Formular tun, wenn eine Änderung in einem seiner Eingabefelder.ngÄnderungsähnliche Funktionalität für das gesamte Formular

Ich weiß, dass seit AngularJS 1.3 Ich habe die Entprellung Option, aber es gilt nur für einen einzigen Eingang.

Ich bin auf der Suche nach einer "Entprellen"/"bei Änderung" -Funktionalität, die für das gesamte Formular gelten wird.

+1

Ich glaube, die beste Wahl, eine Richtlinie für alle Eingaben machen (die Sie wollen debounce auf) und stellen Sie die debounce dort einstellen , aber lass es das ng-Modell und andere Sachen aus deinen Eingaben bestehen. –

Antwort

49

Es gibt keine integrierte in der Weise, ng-change für ein Formular zu tun.

Es ist nicht einmal notwendig sein kann, denn wenn Sie die Ansicht Modell richtig platziert und dann Ihre Formulareingaben wahrscheinlich bis zu einem gewissen Umfang lichteten Eigenschaft gebunden sind:

$scope.formData = {}; 

und in der Ansicht:

<form name="form1"> 
    <input ng-model="formData.a"> 
    <input ng-model="formData.b"> 
</form> 

Dann könnte man tief beobachten (mit $watch) für Modelländerungen (und anzuwenden, ohne dass debounce Option auf Elemente, die Sie benötigen):

$scope.$watch("formData", function(){ 
    console.log("something has changed"); 
}, true); 

Dann ist das Problem, natürlich, dass dies eine Deep-Watch ist und es teuer ist. Außerdem reagiert es nicht nur auf Änderungen in der Form, sondern auch auf eine Veränderung von einer beliebigen Quelle in formData.

So könnten Sie als Alternative eine eigene Anweisung erstellen, um das Formular zu ergänzen und auf Änderungsereignisse des Formulars zu reagieren.

.directive("formOnChange", function($parse){ 
    return { 
    require: "form", 
    link: function(scope, element, attrs){ 
     var cb = $parse(attrs.formOnChange); 
     element.on("change", function(){ 
      cb(scope); 
     }); 
    } 
    } 
}); 

und die Nutzung ist:

<form name="form1" form-on-change="doSomething()"> 
    <input ng-model="formData.a"> 
    <input ng-model="formData.b"> 
</form> 

plunker zur Illustration.

Beachten Sie, dass die „change“ -Ereignis nur auf Blur für eine Texteingabe ausgelöst wird, wie pro jQuery documentation:

Das change Ereignis zu einem Element gesendet wird, wenn sich sein Wert ändert. Diese Veranstaltung ist beschränkt auf <input> Elemente, <textarea> Boxen und <select> Elemente.Bei Auswahlfeldern, Kontrollkästchen und Optionsfeldern wird das Ereignis sofort ausgelöst, wenn der Benutzer eine Auswahl mit der Maus trifft. Bei den anderen Elementtypen wird das Ereignis jedoch zurückgestellt, bis das Element den Fokus verliert.

+1

Sie können auch Texteingabeänderungen erkennen, indem Sie auch auf Tastaturereignisse in dieser Anweisung lauschen, fügen Sie hinzu: 'element.bind (" keydown keypress ", Funktion (Ereignis) { cb (Bereich); });' –

+0

Ist es auch möglich, einige Typen auszuschließen (Eingabe, Auswahl, Schaltfläche usw.)? Ich habe das Click-Ereignis hinzugefügt und versuche, den Button-Typ auszuschließen. Ich kann die Schaltfläche mit console.log (attrs) protokolliert sehen; –

7

one „Hacky“ Weg, dies zu tun ist durch einen Beobachter in die Form schmutzig, gültig je nach Ihren Anforderungen einstellen Sie so etwas wie

$scope.$watch('form.$dirty',function(v){ 
     if(!v){return} 
     form.$setPristine() 
     /*do something here*/ 
    }) 
tun können

dies jedes Mal ausführen wird das Formular geändert wird, wenn Sie nur wollen Ihren Code auf gültige modifizierte Form ausführen können Sie

 if(!v || form.$invalid){return} 

tun und wenn Sie Ihren Code ausführen möchten, wenn das Formular Schritte auf $ gültigen Zustand nur Ihre Beobachter für ‚Form müssen einzurichten. $ gültig '

Wenn Sie Ihren Scope nicht mit Beobachtern verschmutzen möchten, können Sie immer eine Anweisung um das Formular erstellen, das ein On-Change-API-Ereignis darstellt und sich intern um den Watcher kümmert

6

Laut Eric Soyke Kommentar können Sie die Überprüfung der Formularänderung auf dem Keyup-Ereignis anschließen.

diese Weise können Sie einfach die eingebaute Richtlinie ng-keyup verwenden:

<form name="form1" ng-keyup="doSomething()"> 
+0

+1 Dies ist die Antwort, die ich brauchte, da die Lösung von New Dev nur funktioniert, wenn der Fokus verloren geht (wie er bereits erwähnt hat), was dem Benutzer nicht die gewünschte Erfahrung gibt. Ty beide obwohl :) –

+1

Würde nicht mit Autofill-Plugins funktionieren (es sei denn, sie auslösen keyup Ereignis). – setec

+0

Dies funktioniert nicht auf Paste mit der Maus arbeiten. – Dementic