我有一个使用$ timeout的轮询工厂但是在$ timeout运行后我无法更新控制器。

时间:2016-09-15 20:04:50

标签: angularjs

请查看下面的工厂和控制器。我想在我的控制器中引用工厂。我希望控制器能够访问API的运行计数。

目前,在$ timeout运行后,我无法使用新值更新控制器。

理想情况下,我想在工厂保留$ timeout,而不是在控制器中。我认为问题是我在$ timeout中没有回调,有人能指出我正确的方向吗?

工厂

angular.module('MyPoller', []).factory('MyPoller', function(
  $http,$filter,$timeout) {
  var data = { response: {}, calls: 0 };

  var poller = function (successCallback) {
        $http.get('https://jsonplaceholder.typicode.com/posts').then(function (r) {
            data.response = r.data;   
            data.calls++;
            successCallback(data);
            $timeout(poller, 10000);
        });
    };

  return {
        poller: poller
  };
});

控制器

angular.module('NavBarCtrl', [])
       .controller('NavBarCtrl', function NavBarCtrl($scope, $document, $window, $dropdown, $modal, $timeout, MyPoller) {

    var ctrl = this;

    MyPoller.poller(function(data) {
        ctrl.numberNewMessages = data.calls;
    });
})

1 个答案:

答案 0 :(得分:0)

您可以通过使用带吸气剂的工厂而不必使用$scope.$watch()来执行此操作。问题是calls是一个原语,因此在第一次读取它之后,Angular将不再自动检查更改,因为它不期望更改原语。如果您改为引用父对象,则Angular将自动监视更改。这是一个简化示例,用于说明您可以执行此操作的一种方法:



angular.module('app', [])
  .factory('dataService', function($timeout) {
    var _data = {
      response: {},
      calls: 0
    };
    var service = {
      get data() {
        return _data;
      }
    };

    function incrementCalls() {
      _data.calls++;
      $timeout(function() {
        incrementCalls();
      }, 2000);
    }

    incrementCalls();
    return service;
  })
  .controller('ctrl', function($scope, dataService) {
    $scope.data = dataService.data;
  });

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  Calls: {{data.calls}}
</div>
&#13;
&#13;
&#13;

更新 - 与上述相同,但不使用吸气剂
更大的问题是您希望引用从服务返回的对象而不是对象上的原始属性。通过引用对象,您可以通过Angular自动连接以监视更改。

&#13;
&#13;
angular.module('app', [])
  .factory('dataService', function($timeout) {
    var _data = {
      response: {},
      calls: 0
    };
    var service = {
      data: _data
    };

    function incrementCalls() {
      _data.calls++;
      $timeout(function() {
        incrementCalls();
      }, 2000);
    }

    incrementCalls();
    return service;
  })
  .controller('ctrl', function($scope, dataService) {
    $scope.data = dataService.data;
  });
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  Calls: {{data.calls}}
</div>
&#13;
&#13;
&#13;