$watch在处理内部数据(例如,插入或删除数据)时如何在Angular指令中触发变量,但不给该变量分配新对象?
$watch
我有一个当前从JSON文件加载的简单数据集。我的Angular控制器可以做到这一点,并定义一些功能:
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() { }; });
我有一个<button>正确地称为$scope.add函数,并且新对象正确插入到$scope.data集合中。每次点击“添加”按钮,我设置的表格都会更新。
<button>
$scope.add
$scope.data
<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!"开始就收到该消息,但在点击“添加”按钮后再也没有收到。
"I see a data change!"
$watch当我只是从data对象中添加/删除对象,而没有获取整个数据集来分配给对象时,如何触发事件data?
data
您需要启用深对象脏检查。默认情况下,angular仅检查您监视的顶级变量的引用。
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,则启用深度脏检查。
请注意,进行深层脏污检查非常 昂贵 。因此,如果您只需要监视children数组而不是整个data变量,则可以直接监视该变量。
scope.$watch('val.children', function(newValue, oldValue) {}, true);
版本1.2.x引入了$ watchCollection
Shallow监视对象的属性,并在任何属性更改时触发(对于数组,这意味着监视数组项;对于对象映射,这意味着监视属性)
scope.$watchCollection('val.children', function(newValue, oldValue) {});