说我有一个专辑列表,用户可以添加专辑
controller.albumList = function($scope, albumService) {
$scope.albums = albumService.query();
$scope.$watch('$scope.albums',function(){
$scope.albums.$save($scope.albums)
})
$scope.addalbum= function(){
$scope.albums.objects.push(album);
}
};
问题是$ watch总是被触发,我甚至没有触发addalbum方法,每次刷新页面时都会创建一个新专辑。
我按照todeMVC angular中的代码
这是示例代码
var todos = $scope.todos = todoStorage.get();
$scope.newTodo = '';
$scope.editedTodo = null;
$scope.$watch('todos', function () {
$scope.remainingCount = filterFilter(todos, { completed: false }).length;
$scope.completedCount = todos.length - $scope.remainingCount;
$scope.allChecked = !$scope.remainingCount;
todoStorage.put(todos);
}, true);
请帮我理解这个
答案 0 :(得分:3)
这是一个解决方案:
$scope.$watch('albums', function(newValue, oldValue) {
if (angular.equals(newValue, oldValue)) {
return;
}
$scope.albums.$save($scope.albums);
}
在观察者注册观察者之后,异步调用侦听器fn(通过$ evalAsync)来初始化观察者。在极少数情况下,这是不合需要的,因为当watchExpression的结果没有改变时会调用监听器。要在侦听器fn中检测此场景,您可以比较newVal和oldVal。如果这两个值相同(===)则由于初始化而调用了监听器。
有关$ watch listener的更多信息:$watch at angularjs docs
答案 1 :(得分:1)
首先,在引用作用域的属性时,不必指定作用域对象。所以,替换:
$scope.$watch('$scope.albums', ...)
以下内容:
$scope$watch('albums', ...)
现在谈谈你的问题。每次被监视的对象/属性的值发生变化时,都会触发$watch
。这甚至包括尚未分配值的情况,例如undefined
和null
。因此,如果您希望仅在添加新相册时才进行保存,则可以使用类似于以下内容的代码:
//Makes assumption that albums has a length property
$scope.$watch('albums.length', function () {
//Check for invalid cases
if ($scope.albums === undefined || $scope.albums === null) {
return;
}
//Genuine cases.
//Proceed to save the album.
});
有了这个,$watch
仍然会在不需要的情况下触发,但通过检查,您可以避免在相册未更改时保存。另请注意,仅当相册对象的长度发生更改时,您的$watch
才会触发。因此,如果相册本身已更新(例如更改现有相册名称),则不会触发此手表。您可以根据需要更改监视属性。此处提到的watch属性仅在添加新相册时有效。