Angular服务手表创建$ digest循环

时间:2014-07-09 11:30:41

标签: angularjs

我正在尝试在服务函数的返回值更改时更新scope。从阅读开始,听起来我应该使用$watch,但是跟随角度docs在我的应用程序中创建了一个无限$digest循环,这里是控制器:

.controller('navCtrl', function(CookieHandler, $scope){
  // this works, but doesn't update when CookieHandler.get() changes
  // $scope.user = CookieHandler.get();

  $scope.$watch(
    function() {return CookieHandler.get()},
    function(newValue, oldValue) {
      if( newValue !== oldValue) {
        $scope.user = newValue
      }
    }
  ) 
  //etc

从错误消息中可以看出在返回数组的函数上使用$ watch,但是CookieHandler.get()会返回一个对象吗?

我环顾了一些,并且读到我应该使用$apply代替$watch,因为它更容易测试,所以我尝试了这个:

.controller('navCtrl', function(CookieHandler, $scope){
  // this works, but doesn't update when CookieHandler.get() changes
  // $scope.user = CookieHandler.get();

  $scope.$apply(function(scope){
    scope.user = CookieHandler.get();
  })
})

但这会引发有关已经运行的摘要周期的错误。有没有办法修复我的$watch以阻止无限循环? CookieHandler.get仅使用$cookieStore

检查值

1 个答案:

答案 0 :(得分:1)

$watch在当前值和前一个摘要周期的值之间执行相等的比较。如果它们不同则执行该功能。

如果CookieHandler.get()返回的对象始终是相同的引用,那么watch函数永远不会被调用。即使您更新该对象的属性。

数组是一个坏主意,因为它们通常总是一个新对象,JavaScript会将它们视为永远不相等。

您可以将对象/数组序列化为JSON并使用该值,但如果键/值顺序发生更改,则无法执行此操作。

看起来您正在尝试监控当前用户的更改时间。假设您有一个用户的唯一标识符,那么您可能想尝试这样的事情。

$scope.$watch(
  function() {
      var user = CookieHandler.get();
      return (typeof user === 'undefined') ? 0 : user.id;
  },
  function(newValue, oldValue) {
    if( newValue !== oldValue) {
      $scope.user = CookieHandler.get();
    }
  }
);

请注意,我两次致电.get()。我不知道你的服务是如何运作的。也许这是不可能的,但重点是观察一个容易比较的价值。