AngularJS: Automatische Erkennung von Modelländerungen
Lesezeit: 4 Minuten
alecbz
Angenommen, ich wollte so etwas wie automatisch ausführen (wie das Speichern von Daten auf einem Server), wenn sich die Werte eines Modells ändern. Ist die einzige Möglichkeit, dies zu tun, indem Sie so etwas wie einstellen ng-change auf jeder Steuerung, die möglicherweise das Modell verändern könnte?
Das heißt, bei Ansichten ändern sich die Dinge direkt, wenn das Modell geändert wird, ohne dass explizit etwas angeschlossen werden muss. Gibt es eine Analogie zur Ausführung von Code, der auf einem Server gespeichert wird? Etwas wie
wie Sie vielleicht mit so etwas wie Backbone sehen.
Markus Rajcok
In Ansichten mit {{}} und/oder ng-model, Angular wird eingerichtet $watch()es für Sie hinter den Kulissen.
Standardmäßig $watch vergleicht per Referenz. Wenn Sie den dritten Parameter auf setzen $watch zu true, Angular überwacht das Objekt stattdessen “flach” auf Änderungen. Für Arrays bedeutet dies, die Array-Elemente zu vergleichen, für Objektkarten bedeutet dies, die Eigenschaften zu beobachten. Das sollte also tun, was Sie wollen:
Beachten Sie, dass das Wort “oberflächlich” verwendet wird, um den Vergleich zu beschreiben, und nicht “tief”, weil Referenzen nicht verfolgt werden — zB wenn das überwachte Objekt einen Eigenschaftswert enthält, der eine Referenz auf ein anderes Objekt ist, wird dieser Referenz nicht gefolgt, um zu vergleichen das andere Objekt.
Ah gut! Gibt es einen Grund, warum dies nicht so dokumentiert zu sein scheint (dh ich glaube nicht, dass eines der Tutorials auf der eckigen Website das direkte Einrichten von $watches erwähnt hat)? Gibt es etwas Schlechtes daran, das die Einrichtung (möglicherweise mehrerer) ng-change Haken bei Eingabesteuerelementen eine bessere Idee?
– Alecbz
15. März 2013 um 3:42 Uhr
Ja, es wäre schön, wenn das Haupt-Tutorial $watch irgendwo erwähnen würde. Das „Schlechte“ an diesem Ansatz ist, dass er zeitaufwändig sein kann, wenn Ihr Modell groß ist (jeder Digest-Zyklus – jeder Tastendruck in einem Eingabefeld – führt dazu, dass dieses Modell gründlich überprüft wird, möglicherweise mehrmals). . In diesem Fall wären selektive $watch()es oder selektive ng-Änderungen besser.
– Markus Rajcok
15. März 2013 um 3:57 Uhr
Und wenn Sie Ihre Formularelemente entsprechend ihrem Status (geändert/nicht geändert) dynamisch formatieren oder testen möchten, ob sich einige Werte tatsächlich geändert haben, können Sie das folgende von mir entwickelte Modul verwenden: https://github.com/betsol/angular-input-modified
Es fügt dem Formular und seinen untergeordneten Elementen zusätzliche Eigenschaften und Methoden hinzu. Damit können Sie testen, ob ein Element neue Daten enthält, oder sogar testen, ob das gesamte Formular neue nicht gespeicherte Daten enthält.
Sie können die folgende Uhr einrichten: $scope.$watch('myForm.modified', handler) und Ihr Handler wird aufgerufen, wenn einige Formularelemente tatsächlich neue Daten enthalten oder in den ursprünglichen Zustand zurückgesetzt wurden.
Außerdem können Sie verwenden modified Eigenschaft einzelner Formularelemente, um die per AJAX-Aufruf an einen Server gesendete Datenmenge tatsächlich zu reduzieren. Es müssen keine unveränderten Daten gesendet werden.
Als Bonus können Sie Ihr Formular per Call-to-Forms in den ursprünglichen Zustand zurückversetzen reset() Methode.
Gibt es eine Möglichkeit, dies in der Steuerung zu überprüfen. Wenn ich zum Beispiel auf die x-Schaltfläche klicke, kann ich ein if(myform.modified)-Bestätigungs-Popup anzeigen?
– Blinken
25. Mai 2017 um 19:05 Uhr
Natürlich übergeben Sie FormController einfach an die Funktion Ihres Controllers: <form name="myForm">, <button ng-click="vm.doSomething(myForm)">.
– Slawa Fomin II
26. Mai 2017 um 19:12 Uhr
danke, das wird nur etwas tun, wenn das Formular geändert wurde, oder?
– Blinken
31. Mai 2017 um 18:30 Uhr
Es wird vorübergehen FormController zum doSomething() Funktion Ihres Controllers. Sie können innerhalb dieser Funktion alles tun, was Sie wollen, z. B. überprüfen, ob das Formular tatsächlich geändert wurde, indem Sie das überprüfen FormController.modified boolesche Eigenschaft.
– Slawa Fomin II
31. Mai 2017 um 19:53 Uhr
Vielen Dank! Schöne Funktion
– Blinken
5. Juni 2017 um 20:50 Uhr
Erkennen Sie Änderungen in einem einzelnen Modell
$scope.$watchCollection('model1', function () {
//...
}, true);
Erkennen Sie Änderungen in mehreren Modellen
$scope.$watchCollection('[model1, model2, model3]', function () {
//...
}, true);
12052000cookie-checkAngularJS: Automatische Erkennung von Modelländerungenyes