I'm trying to figure out why my $watch
isn't being triggered. This is a snippet from the relevant controller:
我想弄明白为什么我的手表没有被触发。这是相关控制器的一个片段:
$scope.$watch('tasks', function (newValue, oldValue) {
//do some stuff
//only enters here once
//newValue and oldValue are equal at that point
});
$scope.tasks = tasksService.tasks();
$scope.addTask = function (taskCreationString) {
tasksService.addTask(taskCreationString);//modifies tasks array
};
On my view, tasks
is clearly being updated correctly as I have its length bound like so:
在我看来,任务显然正在被正确地更新,因为我有它的长度范围如下:
<span>There are {{tasks.length}} total tasks</span>
What am I missing?
我缺少什么?
4 个解决方案
#1
132
Try $watch('tasks.length', ...)
or $watch('tasks', function(...) { ... }, true)
.
尝试看美元(的任务。长度”,…)或看美元(“任务”,函数(…){…},真正的)。
By default, $watch does not check for object equality, but just for reference. So, $watch('tasks', ...)
will always simply return the same array reference, which isn't changing.
默认情况下,$watch不检查对象是否相等,只检查对象是否相等。因此,$watch('tasks',…)总是只返回相同的数组引用,不会改变。
Update: Angular v1.1.4 adds a $watchCollection() method to handle this case:
更新:角v1.1.4添加了$watchCollection()方法来处理这种情况:
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). If a change is detected the
listener
callback is fired.浅视图监视对象的属性,并在任何属性发生更改时触发(对于数组,这意味着监视数组项,对于对象映射,这意味着监视属性)。如果检测到更改,则触发侦听器回调。
#2
13
Very good answer by @Mark. In addition to his answer, there is one important functionality of $watch
function you should be aware of.
@Mark的回答很好。除了他的答案之外,您还应该注意$watch函数的一个重要功能。
With the $watch
function declaration as follows:
$watch功能声明如下:
$watch(watch_expression, listener, objectEquality)
The $watch
listener function is called only when the value from the current watch expression (in your case it is 'tasks'
) and the previous call to watch expression are not equal. Angular saves the value of the object for later comparison. Because of that, watching complex options will have disadvantageous memory and performance implications. Basically the simpler watch expression value the better.
只有当当前监视表达式的值(在您的示例中是“tasks”)和之前对监视表达式的调用不相等时,才调用$watch侦听器函数。角保存对象的值以便以后进行比较。正因为如此,观察复杂的选项将对内存和性能产生不利影响。基本上,手表表达越简单越好。
#3
5
I would recommend trying
我建议尝试
$scope.$watch('tasks | json', ...)
That will catch all changes to the tasks
array, as it compares the serialized array as a string.
这将捕获对tasks数组的所有更改,因为它将序列化数组作为字符串进行比较。
#4
3
For one dimensional arrays you may use $watchCollection
对于一维数组,可以使用$watchCollection
$scope.names = ['igor', 'matias', 'misko', 'james'];
$scope.dataCount = 4;
$scope.$watchCollection('names', function(newNames, oldNames) {
$scope.dataCount = newNames.length;
});
#1
132
Try $watch('tasks.length', ...)
or $watch('tasks', function(...) { ... }, true)
.
尝试看美元(的任务。长度”,…)或看美元(“任务”,函数(…){…},真正的)。
By default, $watch does not check for object equality, but just for reference. So, $watch('tasks', ...)
will always simply return the same array reference, which isn't changing.
默认情况下,$watch不检查对象是否相等,只检查对象是否相等。因此,$watch('tasks',…)总是只返回相同的数组引用,不会改变。
Update: Angular v1.1.4 adds a $watchCollection() method to handle this case:
更新:角v1.1.4添加了$watchCollection()方法来处理这种情况:
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). If a change is detected the
listener
callback is fired.浅视图监视对象的属性,并在任何属性发生更改时触发(对于数组,这意味着监视数组项,对于对象映射,这意味着监视属性)。如果检测到更改,则触发侦听器回调。
#2
13
Very good answer by @Mark. In addition to his answer, there is one important functionality of $watch
function you should be aware of.
@Mark的回答很好。除了他的答案之外,您还应该注意$watch函数的一个重要功能。
With the $watch
function declaration as follows:
$watch功能声明如下:
$watch(watch_expression, listener, objectEquality)
The $watch
listener function is called only when the value from the current watch expression (in your case it is 'tasks'
) and the previous call to watch expression are not equal. Angular saves the value of the object for later comparison. Because of that, watching complex options will have disadvantageous memory and performance implications. Basically the simpler watch expression value the better.
只有当当前监视表达式的值(在您的示例中是“tasks”)和之前对监视表达式的调用不相等时,才调用$watch侦听器函数。角保存对象的值以便以后进行比较。正因为如此,观察复杂的选项将对内存和性能产生不利影响。基本上,手表表达越简单越好。
#3
5
I would recommend trying
我建议尝试
$scope.$watch('tasks | json', ...)
That will catch all changes to the tasks
array, as it compares the serialized array as a string.
这将捕获对tasks数组的所有更改,因为它将序列化数组作为字符串进行比较。
#4
3
For one dimensional arrays you may use $watchCollection
对于一维数组,可以使用$watchCollection
$scope.names = ['igor', 'matias', 'misko', 'james'];
$scope.dataCount = 4;
$scope.$watchCollection('names', function(newNames, oldNames) {
$scope.dataCount = newNames.length;
});