new - AngularJS $ watch vs $ watchCollection: ¿cuál es mejor para el rendimiento?
rootscope watch (3)
La función
$watchCollection()
es una especie de campo intermedio entre las dos configuraciones$watch()
anteriores. Es más profundo que la función vanilla $ watch (); pero, no es tan costoso como la función$watch()
igualdad profunda. Al igual que la función$watch()
,$watchCollection()
funciona al comparar referencias físicas de objetos; sin embargo, a diferencia de la función$watch()
,$watchCollection()
un nivel de profundidad y realiza una comprobación de referencia adicional y superficial de los elementos de nivel superior de la colección.
Para ver una variable de alcance de objeto, es $scope.$watch
objectEquality
con objectEquality
establecido en true o $scope.$watchCollection
Para una variable de objeto $scope
(como 15 atributos, algunos niveles anidados de profundidad 2) actualizados con elementos de entrada y ng-model
en la vista, ¿qué tan malo es $scope.$watch
objectEquality
with objectEquality
establecido en true
? ¿Es esto una gran cosa para evitar?
¿Es $watchCollection
una mejor solución?
Estoy buscando ganancias fáciles para mejorar el rendimiento en mi aplicación AngularJS (todavía estoy atascado en v1.2.2).
// ctrl scope var
$scope.filters = {
name: '''',
info: {test: '''', foo: '''', bar: ''''},
yep: ''''
// etc ...
}
// ctrl watch ?
$scope.$watch(''filters'', function(newVal, oldVal) {
if(newVal !== oldVal) {
// call with updated filters
}
}, true);
// or ctrl watch collection ?
$scope.$watchCollection(''filters'', function(newVal, oldVal) {
if(newVal !== oldVal) {
// call with updated filters
}
});
// view input with ng-model
<input type="text" ng-model="filters.name" />
<input type="text" ng-model="filters.info.test" />
<input type="text" ng-model="filters.yep" />
// etc ...
$watchCollection
está optimizado para arrays []
vectoriales arrays []
donde los elementos se pueden empujar
y $watch
es bueno para los objetos de matrices asociativas {}
$watchCollection
no observará los cambios de profundidad, es como ver con objectEquality establecido en falso.
Si ya sabes estructurar la profundidad puedes optimizar así:
// ctrl watch ?
$scope.$watch(''filters'', function(newVal, oldVal) {
if(newVal !== oldVal) {
// call with updated filters
}
});
// ctrl watch ?
$scope.$watch(''filters.info'', function(newVal, oldVal) {
if(newVal !== oldVal) {
// call with updated filters
}
});
$ watch () será activado por:
$scope.myArray = [];
$scope.myArray = null;
$scope.myArray = someOtherArray;
$ watchCollection () se activará por todo lo que está arriba Y:
$scope.myArray.push({}); // add element
$scope.myArray.splice(0, 1); // remove element
$scope.myArray[0] = {}; // assign index to different value
$ watch (..., true) se activará TODO LO QUE se encuentra arriba Y:
$scope.myArray[0].someProperty = "someValue";
SOLO UNA COSA MÁS...
$ watch () es el único que se activa cuando una matriz se reemplaza por otra con el mismo contenido exacto. Por ejemplo:
$scope.myArray = ["Apples", "Bananas", "Orange" ];
var newArray = [];
newArray.push("Apples");
newArray.push("Bananas");
newArray.push("Orange");
$scope.myArray = newArray;
A continuación se muestra un enlace a un ejemplo de JSFiddle que utiliza todas las diferentes combinaciones de relojes y envía mensajes de registro para indicar qué "relojes" se activaron: