$ watch未被触发阵列更改
我试图找出为什么我的$watch
未被触发。这是从相关的控制器的一个片段:
<span>There are {{tasks.length}} total tasks</span>
我缺少什么:
$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
显然被正确,因为我已经其长度必然像这样更新?
尝试$watch('tasks.length', ...)
或$watch('tasks', function(...) { ... }, true)
。
默认情况下,$watch不检查对象相等性,但仅供参考。所以,$watch('tasks', ...)
将总是简单地返回相同的数组引用,这是不变的。
更新:角V1.1.4添加$watchCollection()方法来处理这种情况:
浅手表的对象和火灾的属性,只要任何性质的改变(对于阵列,这意味着观看阵列项目,对于这意味着观看属性的对象地图)。如果检测到更改,则会触发
listener
回调。
非常好的回答@Mark。除了他的回答,还有一个重要的功能$watch
你应该知道。
随着$watch
函数声明如下:
$watch(watch_expression, listener, objectEquality)
的$watch
监听函数被调用,只有当从当前监视表达式值(在你的情况下,它是'tasks'
),以前的呼叫到手表表情不相等。 Angular保存对象的值以供以后比较。因此,观看复杂的选项将会产生不利的记忆和性能影响。基本上更简单的手表表示值越好。
+1。我会提到(为了完整性),监听器函数在初始化时也被调用来初始化监视器。如果'watch_expression'没有改变,这需要发生。 – 2013-03-12 21:01:05
是的...复制文档。 https://docs.angularjs.org/api/ng/type/$rootScope.Scope – hupseb 2014-07-08 13:13:32
我会建议您尝试
$scope.$watch('tasks | json', ...)
,将捕获所有更改tasks
阵列,因为它的序列化数组作为字符串进行比较。
对于一个维数组,你可以使用$watchCollection
$scope.names = ['igor', 'matias', 'misko', 'james'];
$scope.dataCount = 4;
$scope.$watchCollection('names', function(newNames, oldNames) {
$scope.dataCount = newNames.length;
});
这似乎是这个问题也适用于观看的对象。相反,你必须看一个特定的财产。 – VSO 2016-05-27 23:43:50