$腕表未触发的阵列变化($watch not being triggered on array ch

2019-07-21 09:49发布

我试图找出为什么我的$watch没有被触发。 这是从相关的控制器的一个片段:

$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
};

在我看来, tasks显然是正确更新,因为我有它的长度约束,像这样:

<span>There are {{tasks.length}} total tasks</span>

我在想什么?

Answer 1:

尝试$watch('tasks.length', ...)$watch('tasks', function(...) { ... }, true)

默认情况下, $手表不检查对象平等,但仅供参考。 所以, $watch('tasks', ...)总是会简单地返回相同的数组引用,这是不会改变。

更新:角V1.1.4增加了$ watchCollection()方法来处理这种情况:

浅手表的对象并且每当任何属性的改变火灾的性能(阵列,这意味着观看阵列的物品,对象映射,这意味着观看属性)。 如果检测到变化的listener回调被触发。



Answer 2:

通过@马克很好的答案。 除了他的回答,还有一个重要的功能$watch功能,你应该知道的。

随着$watch函数声明如下:

$watch(watch_expression, listener, objectEquality)

$watch 监听功能被称为只有当从当前监视表达式的值(在你的情况下,它是'tasks' ),以前的呼叫收看表达是不相等的。 角节省了后面的比较对象的值。 正因为如此,看复杂的选项将有利于内存和性能的影响。 基本上,简单的监视表达式值越大越好。



Answer 3:

我会建议您尝试

$scope.$watch('tasks | json', ...)

这将捕获所有更改tasks阵列,因为它的序列化数组作为字符串进行比较。



Answer 4:

对于一个维数组,你可以使用$ watchCollection

$scope.names = ['igor', 'matias', 'misko', 'james'];
$scope.dataCount = 4;

$scope.$watchCollection('names', function(newNames, oldNames) {
  $scope.dataCount = newNames.length;
});


文章来源: $watch not being triggered on array change