Respostas:
A partir do AngularJS 1.3, existe um novo método chamado $watchGroup
para observar um conjunto de expressões.
$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
e oldValues
como undefined
, enquanto observa individualmente as propriedades funcionar normalmente.
A partir do AngularJS 1.1.4, você pode 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
});
Exemplo de Plunker aqui
Documentação aqui
$watchCollection
objetivo é entregar um objeto e fornecer um controle de alterações em qualquer uma das propriedades do objeto, enquanto que o $watchGroup
objetivo é fornecer uma variedade de propriedades individuais para observar alterações. Um pouco diferente para lidar com problemas semelhantes, mas diferentes. Ufa!
$watch
O primeiro parâmetro também pode ser uma função.
$scope.$watch(function watchBothItems() {
return itemsCombinedValue();
}, function whenItemsChange() {
//stuff
});
Se seus dois valores combinados forem simples, o primeiro parâmetro é apenas uma expressão angular normalmente. Por exemplo, nome e sobrenome:
$scope.$watch('firstName + lastName', function() {
//stuff
});
fullName = firstName + " " + lastName
requer passar uma função como o primeiro argumento (em vez de uma expressão simples como 'firstName, lastName'
). O Angular é TÃO poderoso, mas há algumas áreas em que pode ser muito mais amigável ao desenvolvedor de maneiras que não parecem comprometer os princípios de desempenho ou design.
$scope.$watch('firstName + lastName', function() {...})
. Você também pode apenas fazer dois relógios: function nameChanged() {}; $scope.$watch('firstName', nameChanged); $scope.$watch('lastName', nameChanged);
. Eu adicionei o caso simples à resposta.
Aqui está uma solução muito semelhante ao seu pseudo-código original que realmente funciona:
$scope.$watch('[item1, item2] | json', function () { });
EDIT: Ok, acho que isso é ainda melhor:
$scope.$watch('[item1, item2]', function () { }, true);
Basicamente, estamos pulando a etapa json, que parecia idiota para começar, mas não estava funcionando sem ela. A chave é o terceiro parâmetro frequentemente omitido, que ativa a igualdade de objetos em oposição à igualdade de referência. Em seguida, as comparações entre nossos objetos de matriz criados realmente funcionam corretamente.
TypeError: Object #<Object> has no method '$watchCollection'
mas esta solução me ajuda a resolver meu problema!
$scope.$watch('[chaptercontent.Id, anchorid]', function (newValues, oldValues) { ... }, true);
Você pode usar funções no $ watchGroup para selecionar os campos de um objeto no escopo.
$scope.$watchGroup(
[function () { return _this.$scope.ViewModel.Monitor1Scale; },
function () { return _this.$scope.ViewModel.Monitor2Scale; }],
function (newVal, oldVal, scope)
{
if (newVal != oldVal) {
_this.updateMonitorScales();
}
});
_this
? O escopo não é carregado para as funções sem defini-lo explicitamente?
Por que não simplesmente envolvê-lo em um forEach
?
angular.forEach(['a', 'b', 'c'], function (key) {
scope.$watch(key, function (v) {
changed();
});
});
Trata-se da mesma sobrecarga de fornecer uma função para o valor combinado, sem precisar se preocupar com a composição do valor .
changed()
é chamado sempre que algo muda em qualquer uma das propriedades. Esse é exatamente o mesmo comportamento como se uma função para o valor combinado fosse fornecida.
O primeiro parâmetro $ watch pode ser expressão ou função angular . Veja a documentação sobre $ scope. $ Watch . Ele contém muitas informações úteis sobre como o método $ watch funciona: quando watchExpression é chamado, como angular compara resultados, etc.
e quanto a:
scope.$watch(function() {
return {
a: thing-one,
b: thing-two,
c: red-fish,
d: blue-fish
};
}, listener...);
true
parâmetro para scope.$watch
(como no seu exemplo), listener()
seria acionado toda vez, porque o hash anônimo tem uma referência diferente a cada vez.
return { a: functionA(), b: functionB(), ... }
. Em seguida, verifico os objetos retornados dos valores novos e antigos.
$scope.$watch('age + name', function () {
//called when name or age changed
});
Aqui, a função será chamada quando os valores de idade e nome forem alterados.
O Angular introduzido $watchGroup
na versão 1.3, usando o qual podemos observar várias variáveis, com um único $watchGroup
bloco
$watchGroup
assume o array como primeiro parâmetro no qual podemos incluir todas as nossas variáveis a serem observadas.
$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]);
});