Há uma matriz de objetos no meu escopo, quero observar todos os valores de cada objeto.
Este é o meu código:
function TodoCtrl($scope) {
$scope.columns = [
{ field:'title', displayName: 'TITLE'},
{ field: 'content', displayName: 'CONTENT' }
];
$scope.$watch('columns', function(newVal) {
alert('columns changed');
});
}
Mas quando eu modifico os valores, por exemplo, mudo TITLE
para TITLE2
, o alert('columns changed')
nunca aparece.
Como observar profundamente os objetos dentro de uma matriz?
Há uma demonstração ao vivo: http://jsfiddle.net/SYx9b/
angular.equals
quando o terceiro argumento recebe um valor booleano ?$watchCollection
$watchCollection
assistirá apenas o "primeiro nível" de uma matriz ou objeto, como eu o entendo. A resposta acima está correta se você precisar prestar atenção mais profunda do que isso. bennadel.com/blog/…Há consequências de desempenho para mergulhar profundamente um objeto no seu $ watch. Às vezes (por exemplo, quando as alterações são apenas push e pop), você pode querer assistir a um valor facilmente calculado, como array.length.
fonte
Se você estiver assistindo apenas uma matriz, pode simplesmente usar este pedaço de código:
exemplo
Mas isso não funcionará com várias matrizes:
exemplo
Para lidar com essa situação, costumo converter as várias matrizes que desejo assistir em JSON:
exemplo
Como o @jssebastian apontou nos comentários,
JSON.stringify
pode ser preferível,angular.toJson
pois ele pode lidar com membros que começam com '$' e também com outros casos possíveis.fonte
$watch
, ele é capaz de fazer o mesmo?Pass true as a third argument to watch an object's properties too.
Veja: cheaptography.com/proloser/cheat-sheets/angularjsangular.toJson
em uma única matriz.Vale a pena notar que no Angular 1.1.xe acima, agora você pode usar $ watchCollection em vez de $ watch. Embora o $ watchCollection pareça criar relógios rasos, ele não funcionará com matrizes de objetos como você espera. Ele pode detectar adições e exclusões na matriz, mas não as propriedades dos objetos dentro das matrizes.
fonte
Aqui está uma comparação das três maneiras pelas quais você pode assistir uma variável de escopo com exemplos:
$ watch () é acionado por:
$ watchCollection () é acionado por tudo acima AND:
$ watch (..., true) é acionado por TUDO acima E:
SÓ MAIS UMA COISA...
$ watch () é o único acionado quando uma matriz é substituída por outra matriz, mesmo que essa outra matriz tenha o mesmo conteúdo exato.
Por exemplo, onde
$watch()
seria acionado e$watchCollection()
não:Abaixo está um link para um exemplo do JSFiddle que usa todas as diferentes combinações de relógios e gera mensagens de log para indicar quais "relógios" foram acionados:
http://jsfiddle.net/luisperezphd/2zj9k872/
fonte
$ watchCollection realiza o que você deseja fazer. Abaixo está um exemplo copiado do site da angularjs http://docs.angularjs.org/api/ng/type/$rootScope.Scope Embora seja conveniente, o desempenho precisa ser levado em consideração, especialmente quando você assiste a uma grande coleção.
fonte
Esta solução funcionou muito bem para mim, estou fazendo isso em uma diretiva:
escopo. $ watch (attrs.testWatch, function () {.....}, true);
o true funciona muito bem e reage a todos os objetos (adicionar, excluir ou modificar um campo).
Aqui está um plunker de trabalho para brincar com ele.
Assistindo profundamente uma matriz no AngularJS
Espero que isso possa ser útil para você. Se você tiver alguma dúvida, sinta-se à vontade para perguntar, tentarei ajudar :)
fonte
No meu caso, eu precisava assistir a um serviço, que contém um objeto de endereço também assistido por vários outros controladores. Fiquei preso em um loop até adicionar o parâmetro 'true', que parece ser a chave do sucesso ao assistir objetos.
fonte
Definir o
objectEquality
parâmetro (terceiro parâmetro) da$watch
função é definitivamente a maneira correta de observar TODAS as propriedades da matriz.Piran responde isso bem o suficiente e menciona
$watchCollection
também.Mais detalhes
O motivo pelo qual estou respondendo uma pergunta já respondida é porque quero ressaltar que a resposta do wizardwerdna não é boa e não deve ser usada.
O problema é que os resumos não acontecem imediatamente. Eles precisam esperar até que o bloco de código atual seja concluído antes de executar. Portanto, assistir o
length
de uma matriz pode realmente perder algumas alterações importantes que$watchCollection
serão detectadas.Suponha esta configuração:
À primeira vista, pode parecer que estes disparariam ao mesmo tempo, como neste caso:
Isso funciona bem o suficiente, mas considere isso:
Observe que o comprimento resultante foi o mesmo, mesmo que a matriz tenha um novo elemento e tenha perdido um elemento, portanto, observe o que
$watch
diz respeito,length
não mudou.$watchCollection
pegou nele, no entanto.O mesmo resultado acontece com um push e pop no mesmo bloco.
Conclusão
Para assistir a todas as propriedades da matriz, use
$watch
a própria matriz com o terceiro parâmetro (objectEquality) incluído e definido como true. Sim, isso é caro, mas às vezes necessário.Para observar quando o objeto entra / sai da matriz, use a
$watchCollection
.NÃO use a
$watch
nalength
propriedade da matriz. Quase não há uma boa razão para pensar nisso.fonte
fonte