让Angular $ interval独立于控制器运行

时间:2015-11-03 19:48:19

标签: javascript angularjs angularjs-directive angularjs-scope

我在may应用程序上有不同的页面,它们有自己的控制器。其中一个有$ interval函数,让我们说一个计时器。单击一个按钮将启动此间隔功能,该功能每秒更新一次。我想拥有的是,我希望能够转到我的应用程序中的任何其他页面(调用不同的控制器),但我希望我的间隔继续运行直到我明确地从第一个控制器停止它。一个 rootScope间隔可以这么说。我该怎么办?

编辑:感谢Chris和Patrick我现在有一个简单的服务,看起来像这样:

  .service('TimerService', function($interval) {
    var promise;
    var timerSeconds = 0;

    this.start = function () {
      promise = $interval(function () {
        timerSeconds++;
      }, 1000);
    };

    this.stop = function () {
      promise.cancel(interval);
      timerSeconds = 0;
    };

    this.getTimer = function() {
      return timerSeconds;
    }
  })

我还在此服务中存储了当前值(timerSeconds)。但是如何将此值同步到我的控制器?该服务递增timerSeconds,并且在我的控制器的开头,我通过其getTimer()函数从该服务读取它,但它显然不会在我的控制器上更新。 如何将此服务属性与我的本地属性同步?

编辑:

当我将我的服务属性定义为一个对象,并将timerSeconds定义为该对象内的数字时(似乎基元无法同步):

var timer = {seconds : 0};

this.getTimer = function() {
  return timer;
}

通过getter从我的控制器获取此对象:

vm.timer = TimerService.getTimer();

他们都是同步的。

2 个答案:

答案 0 :(得分:2)

如果您想在控制器之间共享任何数据,正确的方法是使用服务。

然后我会创建一个允许您停止并启动此计时器/间隔的服务。

初始控制器会启动它,它将继续“打勾”直到它停止。

答案 1 :(得分:2)

不要把它添加到$ rootScope。使用可在应用程序中的任何位置使用的服务。这是一个可以启动和停止的单例计时器。在服务本身中定义intervalTimeout,或者如果你想要非常灵活,可以在提供者中这样做(这个例子可能有点过分)。



angular.module('myApp', [])

.service('AppCallback', function ($interval) {
    var states = states = {
        PENDING: 0,
        STARTED: 1
    }, intervalTimeout = 3000, // Set this
    interval;

    this.states = states;
  
    this.state = states.PENDING;
    this.start = function (callback) {
        if (this.state !== states.PENDING) {
            return;
        }

        interval = $interval(callback, intervalTimeout);
        this.state = states.STARTED;
    }

    this.stop = function () {
        if (this.state !== states.STARTED) {
            return;
        }
        $interval.cancel(interval);
        this.state = states.PENDING;
    };
})

.controller('MainController', function ($scope, AppCallback) {
  var vm = {},
      count = 0;
  
  vm.toggle = function toggle() {
    if (AppCallback.state === AppCallback.states.PENDING) {
      AppCallback.start(function () {
        vm.data = 'Ticked ' + (++count) + ' times.';
      });
     } else {
       AppCallback.stop();
     }
  };
  
  
  $scope.vm = vm;
});

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MainController">
  {{vm.data}}
  <br />
  <button ng-click="vm.toggle()">Toggle</button>
</div>
&#13;
&#13;
&#13;