$监视Angular指令中的数据更改

如何在Angular指令中触发一个$watchvariables来处理数据(例如,插入或删除数据),而不是将一个新的对象赋值给该variables?

我有一个简单的数据集,目前正从JSON文件加载。 我的angular度控制器做到这一点,以及定义一些function:

 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() { }; }); 

我有一个适当调用$scope.add函数的<button> ,并且新的对象被正确地插入到$scope.data集合中。 每次点击“添加”button时,我设置的表格都会更新。

 <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> 

然而,我设置的一个指令来监视$scope.data在所有这些情况发生时并没有被触发。

我用HTML定义了我的标签:

 <d3-visualization val="data"></d3-visualization> 

哪一个与下面的指令有关(修正问题的完整性):

 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!"); }); } } }); 

我得到了"I see a data change!" 消息在一开始,但从来没有在我点击“添加”button之后。

当我只是从data对象中添加/删除对象时,如何才能触发$watch事件,而不是获取要分配给data对象的全新数据集?

您需要启用深层对象脏检查。 默认情况下,angular度只检查您所观察的顶级variables的引用。

 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!"); }, true); } } }); 

见范围 。 如果$ watch函数的第三个参数设置为true,则可以进行深度脏检查。

请注意深度脏检查是昂贵的 。 所以,如果你只是需要观看儿童数组而不是整个datavariables,直接观看variables。

 scope.$watch('val.children', function(newValue, oldValue) {}, true); 

版本1.2.x引入了$ watchCollection

浅注意一个对象的属性,并在任何属性改变时触发(对于数组,这意味着要观看数组项;对于对象映射,这意味着要注意属性)

 scope.$watchCollection('val.children', function(newValue, oldValue) {}); 

我的版本是一个指令,它使用jqplot绘制数据一旦可用:

  app.directive('lineChart', function() { $.jqplot.config.enablePlugins = true; return function(scope, element, attrs) { scope.$watch(attrs.lineChart, function(newValue, oldValue) { if (newValue) { // alert(scope.$eval(attrs.lineChart)); var plot = $.jqplot(element[0].id, scope.$eval(attrs.lineChart), scope.$eval(attrs.options)); } }); } }); 

因为如果你想深入触发你的数据,你必须传递你的监听器的第三个参数为true 。默认情况下它是false ,只有当你的variables变化而不是字段时,你的函数才会触发。