In meinem Bereich befindet sich eine Reihe von Objekten. Ich möchte alle Werte jedes Objekts überwachen.
Das ist mein Code:
function TodoCtrl($scope) {
$scope.columns = [
{ field:'title', displayName: 'TITLE'},
{ field: 'content', displayName: 'CONTENT' }
];
$scope.$watch('columns', function(newVal) {
alert('columns changed');
});
}
Aber wenn ich die Werte ändere, z. B. zu ändere TITLE
, TITLE2
ist das alert('columns changed')
nie aufgetaucht.
Wie kann man die Objekte in einem Array genau beobachten?
Es gibt eine Live-Demo: http://jsfiddle.net/SYx9b/
angular.equals
wenn das dritte Argument einen booleschen Wert annimmt ?$watchCollection
$watchCollection
Ich werde nur die "erste Ebene" eines Arrays oder Objekts beobachten, so wie ich es verstehe. Die obige Antwort ist richtig, wenn Sie tiefer schauen müssen. bennadel.com/blog/…Das Tieftauchen eines Objekts in Ihrer $ watch hat Leistungsfolgen. Manchmal (z. B. wenn Änderungen nur Pushs und Pops sind) möchten Sie möglicherweise einen leicht zu berechnenden Wert wie array.length $ beobachten.
quelle
Wenn Sie nur ein Array ansehen möchten, können Sie einfach diesen Code verwenden:
Beispiel
Dies funktioniert jedoch nicht mit mehreren Arrays:
Beispiel
Um diese Situation zu bewältigen, konvertiere ich normalerweise die mehreren Arrays, die ich beobachten möchte, in JSON:
Beispiel
Wie @jssebastian in den Kommentaren hervorhob, ist dies
JSON.stringify
möglicherweise vorzuziehenangular.toJson
da es Mitglieder behandeln kann, die mit '$' beginnen, sowie mögliche andere Fälle.quelle
$watch
gibt, kann er dasselbe tun?Pass true as a third argument to watch an object's properties too.
Siehe: cheatography.com/proloser/cheat-sheets/angularjsangular.toJson
auf einem einzelnen Array.Es ist erwähnenswert, dass Sie in Angular 1.1.x und höher jetzt $ watchCollection anstelle von $ watch verwenden können. Obwohl die $ watchCollection flache Uhren zu erstellen scheint, funktioniert sie nicht mit Arrays von Objekten, wie Sie es erwarten. Es kann Hinzufügungen und Löschungen zum Array erkennen, jedoch nicht die Eigenschaften von Objekten in Arrays.
quelle
Hier ist ein Vergleich der drei Möglichkeiten, wie Sie eine Bereichsvariable mit Beispielen anzeigen können:
$ watch () wird ausgelöst durch:
$ watchCollection () wird durch alles über AND ausgelöst:
$ watch (..., true) wird durch ALLES über AND ausgelöst:
NUR NOCH EINE SACHE...
$ watch () ist die einzige, die ausgelöst wird, wenn ein Array durch ein anderes Array ersetzt wird, selbst wenn dieses andere Array denselben exakten Inhalt hat.
Zum Beispiel, wo
$watch()
würde feuern und$watchCollection()
nicht:Unten finden Sie einen Link zu einem Beispiel für JSFiddle, das alle verschiedenen Uhrenkombinationen verwendet und Protokollmeldungen ausgibt, um anzugeben, welche "Uhren" ausgelöst wurden:
http://jsfiddle.net/luisperezphd/2zj9k872/
quelle
$ watchCollection erreicht, was Sie tun möchten. Unten finden Sie ein Beispiel, das von der AngularJS-Website http://docs.angularjs.org/api/ng/type/$rootScope.Scope kopiert wurde. Obwohl dies praktisch ist, muss die Leistung berücksichtigt werden, insbesondere wenn Sie eine große Sammlung ansehen.
quelle
Diese Lösung hat bei mir sehr gut funktioniert, ich mache das in einer Direktive:
scope. $ watch (attrs.testWatch, function () {.....}, true);
Das wahre funktioniert ziemlich gut und reagiert auf alle Änderungen (Hinzufügen, Löschen oder Ändern eines Feldes).
Hier ist ein funktionierender Plunker zum Spielen.
Ein Array in AngularJS genau beobachten
Ich hoffe, das kann für Sie nützlich sein. Wenn Sie Fragen haben, zögern Sie nicht zu fragen, ich werde versuchen zu helfen :)
quelle
In meinem Fall musste ich einen Dienst überwachen, der ein Adressobjekt enthält, das auch von mehreren anderen Controllern überwacht wird. Ich steckte in einer Schleife fest, bis ich den Parameter 'true' hinzufügte, der der Schlüssel zum Erfolg beim Betrachten von Objekten zu sein scheint.
quelle
Das Einstellen des
objectEquality
Parameters (dritter Parameter) der$watch
Funktion ist definitiv die richtige Methode, um ALLE Eigenschaften des Arrays zu überwachen.Piran antwortet gut genug und erwähnt es
$watchCollection
auch.Mehr Details
Der Grund, warum ich eine bereits beantwortete Frage beantworte, ist, dass ich darauf hinweisen möchte, dass die Antwort von wizardwerdna nicht gut ist und nicht verwendet werden sollte.
Das Problem ist, dass die Digests nicht sofort stattfinden. Sie müssen warten, bis der aktuelle Codeblock vollständig ist, bevor sie ausgeführt werden. Beobachten Sie daher, wie das
length
Array tatsächlich einige wichtige Änderungen übersieht,$watchCollection
die abfangen werden.Nehmen Sie diese Konfiguration an:
Auf den ersten Blick scheint es, als würden diese gleichzeitig feuern, wie in diesem Fall:
Das funktioniert gut genug, aber bedenken Sie Folgendes:
Beachten Sie, dass die resultierende Länge war die gleiche , obwohl das Array ein neues Element hat und verloren ein Element, um zusehen , wie das
$watch
geht,length
hat sich nicht geändert.$watchCollection
nahm es jedoch auf.Das gleiche Ergebnis wird mit einem Push and Pop im selben Block erzielt.
Fazit
Um jede Eigenschaft im Array zu überwachen, verwenden Sie a
$watch
für das Array selbst, wobei der dritte Parameter (objectEquality) enthalten ist und auf true gesetzt ist. Ja, das ist teuer, aber manchmal notwendig.Verwenden Sie a, um zu beobachten, wann ein Objekt das Array betritt / verlässt
$watchCollection
.Verwenden Sie NICHT a
$watch
für dielength
Eigenschaft des Arrays. Es gibt fast keinen guten Grund, warum ich mir das vorstellen kann.quelle
quelle