Quero observar as alterações em um dicionário, mas, por algum motivo, o retorno de chamada do relógio não é chamado.
Aqui está um controlador que eu uso:
function MyController($scope) {
$scope.form = {
name: 'my name',
surname: 'surname'
}
$scope.$watch('form', function(newVal, oldVal){
console.log('changed');
});
}
Aqui está o violino .
Espero que o retorno de chamada $ watch seja acionado sempre que o nome ou sobrenome for alterado, mas isso não acontece.
Qual é a maneira correta de fazer isso?
javascript
angularjs
angularjs-scope
Vladimir Sidorenko
fonte
fonte
Respostas:
Ligue
$watch
comtrue
o terceiro argumento:Por padrão, ao comparar dois objetos complexos em JavaScript, eles serão verificados quanto à igualdade de "referência", que pergunta se os dois objetos se referem à mesma coisa, em vez de igualdade de "valor", que verifica se os valores de todas as propriedades daquelas objetos são iguais.
De acordo com a documentação angular , o terceiro parâmetro é para
objectEquality
:fonte
true
, ele verificará a igualdade de referência se o valor monitorado for um objeto ou matriz. Nesse caso, você deve especificar as propriedades de forma explícita, como$scope.$watch('form.name')
e$scope.$watch('form.surname')
O
form
objeto não está sendo alterado, apenas aname
propriedade éviolino atualizado
fonte
Pouca dica de desempenho se alguém tiver um tipo de serviço de armazenamento de dados com pares chave -> valor:
Se você tiver um serviço chamado dataStore , poderá atualizar um carimbo de data / hora sempre que seu objeto de big data for alterado. Dessa forma, em vez de observar profundamente o objeto inteiro, você está observando apenas um carimbo de data e hora para alterações.
E em uma diretiva, você está apenas observando o carimbo de data e hora para mudar
fonte
newVal
,oldVal
neste exemplo, os valores de carimbo de data e hora e não os valores de objetos observados. Não invalida esta resposta, apenas acho que é uma desvantagem que vale a pena mencionar.O motivo pelo qual seu código não funciona é porque,
$watch
por padrão, a verificação de referência. Então, em poucas palavras, certifique-se de que o objeto que é passado para ele seja um novo objeto. Mas no seu caso, você está apenas modificando alguma propriedade do objeto de formulário e não criando uma nova. Para fazê-lo funcionar, você pode passartrue
como o terceiro parâmetro.Funcionará, mas você pode usar $ watchCollection, que será mais eficiente do que $ watch, porque
$watchCollection
observará propriedades rasas no objeto de formulário. Por exemplofonte
Enquanto você procura alterações no objeto de formulário, a melhor abordagem de observação é usar
$watchCollection
. Consulte a documentação oficial para diferentes características de desempenho.fonte
Tente o seguinte:
fonte
Para quem deseja observar uma alteração em um objeto em uma variedade de objetos, isso pareceu funcionar para mim (como as outras soluções nesta página não):
fonte
fonte