Hier ist eine vereinfachte Anleitung zur Veranschaulichung. Wenn ich in die Eingabe tippe, erwarte ich, dass console.log
in loadResults
genau abliest, was ich bereits eingegeben habe. Es wird tatsächlich ein Zeichen zurückgeschrieben, da loadResults
gerade ausgeführt wird, bevor die searchFilter
var im Hauptcontroller den neuen Wert von der Direktive empfängt. Logging innerhalb der Richtlinie funktioniert jedoch wie erwartet. Warum passiert das?
Meine Lösung
Nachdem ich in meinem einfachen Beispiel verstanden hatte, was mit ngChange passierte, wurde mir klar, dass mein tatsächliches Problem etwas komplizierter war, weil das ngModel, das ich gerade übergebe, ein Objekt ist, dessen Eigenschaften ich verändere und Außerdem verwende ich die Formularvalidierung mit dieser Direktive als eine der Eingaben. Ich fand, dass die Verwendung von $ timeout und $ eval innerhalb der Direktive alle meine Probleme löste:
%Vor% Sie haben Ihre eigene Frage im Titel beantwortet! '='
wird überwacht, während '&'
nicht
Irgendwo außerhalb eckig:
Eingabeansicht ändert sich
nächster Digest-Zyklus:
ng-model
value ändert und feuert ng-change()
ng-change fügt einen $ viewChangeListener hinzu und heißt dieser selbe Zyklus. Sehen: ngModel.js # L714 und ngChange.js Implementierung.
Zu diesem Zeitpunkt wurde $scope.searchFilter
nicht aktualisiert. Der alte Wert von Console.log
searchFilter
wird durch Datenbindung aktualisiert. UPDATE: Nur als eine POC, die Sie benötigen einen zusätzlichen Zyklus für den Wert zu propagieren, können Sie Folgendes tun. Siehe den anderen Anwser (@NewDev für einen saubereren Ansatz).
%Vor% Wie in einer anderen Antwort richtig ausgeführt, liegt der Grund für das Verhalten darin, dass die Zweiwegbindung keine Chance hatte, die äußere searchFilter
um die Zeit searchChange()
und folglich loadResults()
zu ändern. wurde aufgerufen.
Die Lösung ist jedoch aus zwei Gründen sehr hacky.
Einer, der Aufrufer (der Benutzer der Direktive), sollte diese Problemumgehungen mit $timeout
nicht kennen müssen. Wenn nichts anderes, sollte $timeout
in der Direktive und nicht im View-Controller ausgeführt worden sein.
Und zwei - ein Fehler, der auch vom OP gemacht wurde - ist, dass die Verwendung von ng-model
mit anderen "Erwartungen" von Benutzern solcher Richtlinien verbunden ist. Wenn ng-model
bedeutet, können andere Direktiven wie Validatoren, Parser, Formatierer und View-Change-Listener (wie ng-change
) daneben verwendet werden. Um es richtig zu unterstützen, muss man require: "ngModel"
, anstatt an seinen Ausdruck über scope: {}
binden. Ansonsten würden die Dinge nicht wie erwartet funktionieren.
So wird's gemacht - für ein anderes Beispiel siehe die offizielle Dokumentation zum Erstellen eines benutzerdefinierten Eingabesteuerelements.
%Vor% Dann funktioniert ng-change
genauso wie andere Direktiven, die ngModel
unterstützen, wie ng-required
.
Tags und Links angularjs angularjs-ng-change isolate-scope