ngChange wird ausgelöst, bevor der Wert den Isolationsbereich verlässt

8
%Vor%

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%     
Robby Allsopp 16.10.2015, 19:27
quelle

2 Antworten

4

Sie haben Ihre eigene Frage im Titel beantwortet! '=' wird überwacht, während '&' nicht

ist
  • 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

  • nächster Digest-Zyklus: 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%     
Alejandro Cotroneo 16.10.2015, 20:36
quelle
10

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 .

    
New Dev 16.10.2015 23:46
quelle