Respuestas:
A partir de AngularJS 1.3 hay un nuevo método llamado $watchGroup
para observar un conjunto de expresiones.
$scope.foo = 'foo';
$scope.bar = 'bar';
$scope.$watchGroup(['foo', 'bar'], function(newValues, oldValues, scope) {
// newValues array contains the current values of the watch expressions
// with the indexes matching those of the watchExpression array
// i.e.
// newValues[0] -> $scope.foo
// and
// newValues[1] -> $scope.bar
});
$scope.$watchGroup(['mycustomctrl.foo', 'mycustomctrl.bar'],...
newValues
y oldValues
como undefined
, mientras veo individualmente que las propiedades funcionan como de costumbre.
Comenzando con AngularJS 1.1.4 puede usar $watchCollection
:
$scope.$watchCollection('[item1, item2]', function(newValues, oldValues){
// do stuff here
// newValues and oldValues contain the new and respectively old value
// of the observed collection array
});
Ejemplo de Plunker aquí
Documentación aquí
$watchCollection
se pretende que se le entregue un objeto y se proporcione una vigilancia de los cambios en cualquiera de las propiedades del objeto, mientras que $watchGroup
se pretende que se le entregue una serie de propiedades individuales para observar los cambios. Ligeramente diferente para abordar problemas similares pero diferentes. ¡Uf!
$watch
El primer parámetro también puede ser una función.
$scope.$watch(function watchBothItems() {
return itemsCombinedValue();
}, function whenItemsChange() {
//stuff
});
Si sus dos valores combinados son simples, el primer parámetro es simplemente una expresión angular normalmente. Por ejemplo, nombre y apellido:
$scope.$watch('firstName + lastName', function() {
//stuff
});
fullName = firstName + " " + lastName
requiere pasar una función como primer argumento (en lugar de una expresión simple como 'firstName, lastName'
). Angular es TAN poderoso, pero hay algunas áreas donde puede ser enormemente más amigable para el desarrollador de manera que no (parece) comprometer el rendimiento o los principios de diseño.
$scope.$watch('firstName + lastName', function() {...})
. También puede simplemente hacer dos relojes: function nameChanged() {}; $scope.$watch('firstName', nameChanged); $scope.$watch('lastName', nameChanged);
. Agregué el caso simple a la respuesta.
Aquí hay una solución muy similar a su pseudocódigo original que realmente funciona:
$scope.$watch('[item1, item2] | json', function () { });
EDITAR: Bien, creo que esto es aún mejor:
$scope.$watch('[item1, item2]', function () { }, true);
Básicamente, estamos omitiendo el paso json, que parecía tonto al principio, pero no estaba funcionando sin él. La clave es el tercer parámetro a menudo omitido que activa la igualdad de objetos en lugar de la igualdad de referencia. Entonces, las comparaciones entre nuestros objetos de matriz creados realmente funcionan bien.
TypeError: Object #<Object> has no method '$watchCollection'
pero esta solución me ayuda a resolver mi problema!
$scope.$watch('[chaptercontent.Id, anchorid]', function (newValues, oldValues) { ... }, true);
Puede usar funciones en $ watchGroup para seleccionar campos de un objeto en alcance.
$scope.$watchGroup(
[function () { return _this.$scope.ViewModel.Monitor1Scale; },
function () { return _this.$scope.ViewModel.Monitor2Scale; }],
function (newVal, oldVal, scope)
{
if (newVal != oldVal) {
_this.updateMonitorScales();
}
});
_this
? ¿No se lleva el alcance a las funciones sin definirlo explícitamente?
¿Por qué no simplemente envolverlo en un forEach
?
angular.forEach(['a', 'b', 'c'], function (key) {
scope.$watch(key, function (v) {
changed();
});
});
Se trata de la misma sobrecarga que proporcionar una función para el valor combinado, sin tener que preocuparse por la composición del valor .
changed()
se invoca cada vez que algo cambia en cualquiera de las propiedades. Ese es exactamente el mismo comportamiento que si se proporcionara una función para el valor combinado.
Una solución un poco más segura para combinar valores podría ser usar lo siguiente como su $watch
función:
function() { return angular.toJson([item1, item2]) }
o
$scope.$watch(
function() {
return angular.toJson([item1, item2]);
},
function() {
// Stuff to do after either value changes
});
El primer parámetro de $ watch puede ser una función o expresión angular . Consulte la documentación sobre $ scope. $ Watch . Contiene mucha información útil sobre cómo funciona el método $ watch: cuándo se llama a watchExpression, cómo angular compara resultados, etc.
qué tal si:
scope.$watch(function() {
return {
a: thing-one,
b: thing-two,
c: red-fish,
d: blue-fish
};
}, listener...);
true
parámetro a to scope.$watch
(como en su ejemplo), listener()
se dispararía cada vez, porque el hash anónimo tiene una referencia diferente cada vez.
return { a: functionA(), b: functionB(), ... }
. Luego verifico los objetos devueltos de los valores nuevos y antiguos entre sí.
$scope.$watch('age + name', function () {
//called when name or age changed
});
Aquí se llamará a la función cuando cambien tanto el valor de edad como el de nombre.
Angular se introdujo $watchGroup
en la versión 1.3 con la que podemos ver múltiples variables, con un solo $watchGroup
bloque
$watchGroup
toma la matriz como primer parámetro en el que podemos incluir todas nuestras variables para ver.
$scope.$watchGroup(['var1','var2'],function(newVals,oldVals){
console.log("new value of var1 = " newVals[0]);
console.log("new value of var2 = " newVals[1]);
console.log("old value of var1 = " oldVals[0]);
console.log("old value of var2 = " oldVals[1]);
});