$ watchCollection无法正常工作

时间:2014-07-09 21:42:17

标签: angularjs

我目前正在尝试将值绑定到作用域然后观察它,但它似乎无法正常工作。 $ watch永远不会被解雇。 Service.info对象并不是范围或任何东西。该服务也是导致信息更改的服务,而不是带有$ watch的控制器。可能导致这个问题吗?

// Service code
function() {
    var info = {
        prop: false
    };

    window.addEventListener('offline', function() {
        info.prop = !info.prop;
    }, false);

    return {
        info: info
    };
}

// Controller code
$scope.info = Service.info;
$scope.$watchCollection('info', function(newValue) {
    if (newValue.prop) {
        doSomething();
    }
});

2 个答案:

答案 0 :(得分:4)

原因

$watchCollection只是shallow watch。因此,观看info只会查找info属性中的更改。如果未添加或更改任何属性,则不会触发监视。要解决此问题,您需要观看info.prop,或者您可以使用$watch并设置标志以使用深度监视 - 但这样性能会降低。

$ watchCollection文档

  

浅看物体的属性并在任何时候发射   属性改变(对于数组,这意味着观察数组   项目;对于对象图,这意味着观察属性)。如果一个   检测到更改,将触发侦听器回调。

演示

jsFiddle

在此演示中,您可以看到,通过操纵info$watchCollection上的info会被触发。操作prop,触发$watchCollection上的info.prop

HTML

<div ng-app ng-controller="ctrl">
    <pre>
        {{ info | json }}
    </pre>
    <button ng-click="change()">
        Change!
    </button>
    <button ng-click="addProp()">
        Affect info!
    </button>
</div>

控制器

function ctrl($scope) {
    $scope.info = {
        prop: {}
    };

    $scope.change = function() {
        $scope.info.prop["dog" + Math.random()] = Math.random();
    }

    $scope.addProp = function() {
        $scope.info["cat" + Math.random()] = Math.random();
    }

    $scope.$watchCollection('info.prop', function(value) {
        if (value) {
            console.log("info.prop has changed!");
        }
    });

    $scope.$watchCollection('info', function(value) {
        if (value.prop) {
            console.log("info has changed!");
        }
    });

    $scope.$watch('info', function(value) {
        if (value) {
            console.log("deep watch triggered");   
        }
    }, true);
};

答案 1 :(得分:1)

所以我明白了。事实证明,我调用此控制器的控制器嵌套在ng-if中。因此,如果ng-if等同于false并且没有呈现与Controller关联的DOM元素,那么我正在观看的$scope实际上并不存在。