angularjs - $ watch wird bei Array-Änderung nicht ausgelöst



angularjs rootscope (3)

Für eindimensionale Arrays können Sie $watchCollection

$scope.names = ['igor', 'matias', 'misko', 'james'];
$scope.dataCount = 4;

$scope.$watchCollection('names', function(newNames, oldNames) {
  $scope.dataCount = newNames.length;
});

https://src-bin.com

Ich versuche herauszufinden, warum meine $watch nicht ausgelöst wird. Dies ist ein Ausschnitt des entsprechenden Controllers:

$scope.$watch('tasks', function (newValue, oldValue) {
    //do some stuff
    //only enters here once
    //newValue and oldValue are equal at that point
});

$scope.tasks = tasksService.tasks();

$scope.addTask = function (taskCreationString) {
    tasksService.addTask(taskCreationString);//modifies tasks array
};

Aus meiner Sicht werden tasks offensichtlich korrekt aktualisiert, da ich ihre Länge wie folgt gebunden habe:

<span>There are {{tasks.length}} total tasks</span>

Was vermisse ich?


Answer #1

Ich würde es empfehlen

$scope.$watch('tasks | json', ...)

Dadurch werden alle Änderungen am tasks Array abgefangen, da das serialisierte Array als String verglichen wird.


Answer #2

Sehr gute Antwort von @Mark. Zusätzlich zu seiner Antwort gibt es eine wichtige Funktion der $watch Funktion, die Sie beachten sollten.

Mit der $watch Funktionsdeklaration wie folgt:

$watch(watch_expression, listener, objectEquality)

Die $watch Listener- Funktion wird nur aufgerufen, wenn der Wert aus dem aktuellen watch-Ausdruck (in Ihrem Fall 'tasks' ) und der vorherige Aufruf des watch-Ausdrucks nicht gleich sind. Angular speichert den Wert des Objekts für den späteren Vergleich. Aus diesem Grund hat das Beobachten komplexer Optionen nachteilige Auswirkungen auf Speicher und Leistung. Grundsätzlich ist der einfachere Ausdruck des Ausdrucks umso besser.





angularjs-scope