我在指令的链接功能中有以下代码:
link: function (scope, elem, attrs, ngModel) {
$(elem).datagrid({
columns: [[
{ field: 'ck', checkbox: 'true' },
{ field: 'ProjectID', title: 'Project ID', width: '30%' },
{ field: 'Name', title: 'Name' }
]]
});
ngModel.$render = function (value) {
$(elem).datagrid('loadData', ngModel.$viewValue);
};
scope.$watch('projectList', function (newValue, oldValue) {
$(elem).datagrid('loadData', ngModel.$viewValue);
});
}
当最初为Array $ scope.projectList分配数据时,两个侦听器都会被触发。我的控制器中的某个地方(仅用于测试)我在$ scope.projectList中添加了另一个元素:
$scope.test = function () {
var project = $scope.projectList[0];
$scope.projectList.push(project);
}
此时没有听众被解雇。有人可以解释为什么会这样吗?
由于
答案 0 :(得分:2)
$watch
仅检查projectList
数组的引用是否已更改,它不会对集合执行深入监视。将数组分配给范围变量时,更改此引用,但随后修改此数组会使引用保持不变。在您的情况下,使用$watchCollection()
方法似乎更合适。
值得注意的是,$watchCollection
仅检查集合元素引用是否已更改,例如通过添加/删除/替换项目。它不会检查这些元素本身是否已被修改。
如果您希望对收藏品进行深入观察,请将true
作为第三个参数传递给$watch()
。
scope.$watch('projectList', function (newValue, oldValue) {
$(elem).datagrid('loadData', ngModel.$viewValue);
}, true); // <--- note the objectEquality flag set to true
但是,请注意,如果集合中的项目很复杂并且需要更多时间来比较它们,这可能会对性能产生影响。
您还可以查看Angular docs的$ scope了解更多信息(向下滚动$watch()
和$watchCollection()
方法说明)。
答案 1 :(得分:1)
这是因为普通的$ watch函数只是看引用相等,所以如果你做了这样的事情:
var project = $scope.projectList[0];
$scope.newProjectList = [];
$scope.newProjectList.push(project);
$scope.projectList = $scope.newProjectList;
然后它会触发你的手表因为$ scope.projectList的对象引用发生了变化。
如果你想要你的例子:
var project = $scope.projectList[0];
$scope.projectList.push(project);
要触发手表,那么你要么必须要做
scope.$watch('projectList', function (newValue, oldValue) {
$(elem).datagrid('loadData', ngModel.$viewValue);
}, true);
(将$作为最后一个参数传递给$ watch会导致$ watch进行深度相等比较,对于大对象或大型列表,这可能会很慢)
OR
scope.$watchCollection('projectList', function (newValue, oldValue) {
$(elem).datagrid('loadData', ngModel.$viewValue);
});
(这与普通$ watch在引用相等方面类似,但它特别针对列表。因此,在主要参考检查之上,它还对集合中的每个项目进行参考检查或者数组,所以它会触发像.push和.pop这样的东西
他们都有自己的优势,这取决于你正在寻找什么样的支票。另外,请记住$ watch返回一个取消注册函数,你可以用它来清除它,你通常会在范围内做。$ on('$ destroy'。如果不这样做,它们只会停留一段时间,如果你有很多,可能会流失。
这是一个很好的 article关于3种口味的手表之间的所有差异