Como posso disparar uma $watch
variável em uma diretiva Angular ao manipular os dados internos (por exemplo, inserir ou remover dados), mas não atribuir um novo objeto a essa variável?
Atualmente, tenho um conjunto de dados simples sendo carregado de um arquivo JSON. Meu controlador Angular faz isso, bem como define algumas funções:
App.controller('AppCtrl', function AppCtrl($scope, JsonService) {
// load the initial data model
if (!$scope.data) {
JsonService.getData(function(data) {
$scope.data = data;
$scope.records = data.children.length;
});
} else {
console.log("I have data already... " + $scope.data);
}
// adds a resource to the 'data' object
$scope.add = function() {
$scope.data.children.push({ "name": "!Insert This!" });
};
// removes the resource from the 'data' object
$scope.remove = function(resource) {
console.log("I'm going to remove this!");
console.log(resource);
};
$scope.highlight = function() {
};
});
Eu tenho uma <button>
que é chamada corretamente de $scope.add
função e o novo objeto é inserido corretamente no $scope.data
conjunto. Uma tabela que eu configurei é atualizada sempre que clico no botão "adicionar".
<table class="table table-striped table-condensed">
<tbody>
<tr ng-repeat="child in data.children | filter:search | orderBy:'name'">
<td><input type="checkbox"></td>
<td>{{child.name}}</td>
<td><button class="btn btn-small" ng-click="remove(child)" ng-mouseover="highlight()"><i class="icon-remove-sign"></i> remove</button></td>
</tr>
</tbody>
</table>
No entanto, uma diretiva que eu configurei para assistir $scope.data
não está sendo acionada quando tudo isso acontece.
Eu defino minha tag em HTML:
<d3-visualization val="data"></d3-visualization>
Que está associado à seguinte diretiva (aparada para sanidade das perguntas):
App.directive('d3Visualization', function() {
return {
restrict: 'E',
scope: {
val: '='
},
link: function(scope, element, attrs) {
scope.$watch('val', function(newValue, oldValue) {
if (newValue)
console.log("I see a data change!");
});
}
}
});
Recebo a "I see a data change!"
mensagem logo no início, mas nunca depois de clicar no botão "adicionar".
Como posso acionar o $watch
evento quando estou apenas adicionando / removendo objetos do data
objeto, sem obter um conjunto de dados totalmente novo para atribuir ao data
objeto?
fonte
if
declaração.Respostas:
Você precisa habilitar a verificação suja de objetos profundos. Por padrão, angular verifica apenas a referência da variável de nível superior que você assiste.
veja Escopo . O terceiro parâmetro da função $ watch permite uma verificação profunda e suja, se estiver definida como true.
Observe que a verificação suja profunda é cara . Portanto, se você precisar apenas observar a matriz filho em vez de toda a
data
variável, observe a variável diretamente.a versão 1.2.x introduziu $ watchCollection
fonte
Como se você deseja acionar seus dados com profundidade, é necessário passar o terceiro argumento
true
do seu ouvinte. Por padrão, éfalse
e me parece que sua função será acionada, apenas quando sua variável mudar, não é o campo .fonte
Minha versão de uma diretiva que usa jqplot para plotar os dados assim que estiverem disponíveis:
fonte