$watchCollection 无法正常工作

Ric*_*yre 1 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();
    }
});
Run Code Online (Sandbox Code Playgroud)

Pet*_*ete 5

原因

$watchCollection只是一个浅表。所以 watchinfo只会寻找info's 属性的变化。如果没有添加或更改属性,则不会触发监视。要解决此问题,您需要监视,info.prop或者您可以使用 a$watch并设置标志以使用深度监视 - 但是这会降低性能。

$watchCollection 文档

Shallow 监视对象的属性并在任何属性更改时触发(对于数组,这意味着监视数组项;对于对象映射,这意味着监视属性)。如果检测到更改,则会触发侦听器回调。

演示

js小提琴

在这个演示中,您可以看到通过操作info,触发了$watchCollectionon info。操纵prop,触发$watchCollectionon 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>
Run Code Online (Sandbox Code Playgroud)

控制器

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);
};
Run Code Online (Sandbox Code Playgroud)