$watch'ing Angular 指令中的数据变化 [英] $watch'ing for data changes in an Angular directive
问题描述
如何在 Angular 指令中操作数据时触发 $watch
变量(例如,插入或删除数据),但不为该变量分配新对象?
How can I trigger a $watch
variable in an Angular directive when manipulating the data inside (e.g., inserting or removing data), but not assign a new object to that variable?
我有一个当前正在从 JSON 文件加载的简单数据集.我的 Angular 控制器执行此操作,并定义了一些函数:
I have a simple dataset currently being loaded from a JSON file. My Angular controller does this, as well as define a few functions:
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
函数,并且新对象正确插入到 $scope.data
设置.每次点击添加"按钮时,我设置的表格都会更新.
I have a <button>
that properly called the $scope.add
function, and the new object is properly inserted into the $scope.data
set. A table I have set up does update each time I hit the "add" 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
的指令并没有被触发.
However, a directive I set set up to watch $scope.data
is not being fired when all this happens.
我在 HTML 中定义我的标签:
I define my tag in HTML:
<d3-visualization val="data"></d3-visualization>
与以下指令相关联(为了问题的完整性进行了修剪):
Which is associated with the following directive (trimmed for question sanity):
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 get the "I see a data change!"
message at the very beginning, but never after as I hit the "add" button.
当我只是从 data
对象中添加/删除对象,而不是将全新的数据集分配给 $watch
时,如何触发 $watch
事件代码>数据代码>对象?
How can I trigger the $watch
event when I'm just adding/removing objects from the data
object, not getting a whole new dataset to assign to the data
object?
推荐答案
您需要启用深度对象脏检查.默认情况下,angular 仅检查您观察的顶级变量的引用.
You need to enable deep object dirty checking. By default angular only checks the reference of the top level variable that you watch.
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.
see Scope. The third parameter of the $watch function enables deep dirty checking if it's set to true.
请注意,深度脏检查昂贵.因此,如果您只需要查看 children 数组而不是整个 data
变量,请直接查看变量.
Take note that deep dirty checking is expensive. So if you just need to watch the children array instead of the whole data
variable the watch the variable directly.
scope.$watch('val.children', function(newValue, oldValue) {}, true);
1.2.x 版引入了 $watchCollection
version 1.2.x introduced $watchCollection
Shallow 监视对象的属性并在任何属性更改时触发(对于数组,这意味着监视数组项;对于对象映射,这意味着监视属性)
Shallow watches the properties of an object and fires whenever any of the properties change (for arrays, this implies watching the array items; for object maps, this implies watching the properties)
scope.$watchCollection('val.children', function(newValue, oldValue) {});
这篇关于$watch'ing Angular 指令中的数据变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!