如何在 angularjs 中为计时器创建单例服务?

How to create singleton service for timer in angularjs?

我正在 angularjs (1.x) 做一个项目。我的要求是我需要计算经过的秒数。

为此,我在我的控制器中使用 $interval 服务编写了一个代码,它运行良好。

现在,由于这段代码被许多对象共享,所以我想把它做成单例。我们该怎么做?

下面是我在控制器中的代码:

scope.timeDiff = 0;
 var intervalId = $interval(function(){
           scope.timeDiff += 1000; 
        },1000);

 scope.$on('$destroy',function(){
           $interval.clear(intervalId);
 });

我试过创建这样的计时器服务:

angular.module('myModule').factory('customTimer', ['$interval','$rootScope',
  function ($interval,$rootScope) {
     var timerId, defaultInterval = 1000;     
     return {
       startTimer: function (timeDiff) {
        $interval(function(){
           timeDiff += 1000;
        },1000);
        return timeDiff;
       }
     };
}]);

然后我尝试在我的控制器中调用此服务,如下所示:

scope.timeDiff = customTimer.startTimer( scope.timeDiff);        
console.log( "new timediff:",scope.timeDiff );

虽然 timeDiff 在我的定时器服务中更新,但控制器始终为 0。可能是什么原因?

首先angular服务和工厂已经是单例了。

唯一的问题是同步问题。

它是异步调用,所以你必须使用回调或承诺来确保它。

在控制器中添加以下方法:

$scope.callback = function(retTime) {
  console.log( "new timediff:",retTime);
}
$scope.timeDiff = customTimer.startTimer( scope.timeDiff, $scope.callback);   

$scope.$on('$destroy',function(){
       customTimer.stopTimer();
}); 

工厂可以这样写:

angular.module('myModule').factory('customTimer', ['$interval','$rootScope',
  function ($interval,$rootScope) {
     var timerId, defaultInterval = 1000;     
     return {
       startTimer: function (timeDiff, callback) {
        timerId = $interval(function(){
           timeDiff += 1000;
        // This if block will ensure your controller callback called after the value of time diff is updated.
           if(callback) {
              callback(timeDiff)
           }
        },1000);
        return timeDiff;
       },
       stopTimer: function () {
         $interval.cancel(timerId);
       }
     };
}]);

angular服务可以这样写:

angular.module('myModule').service('customTimer', ['$interval','$rootScope',
  function ($interval,$rootScope) {
     var self = this;
     self.defaultInterval = 1000;     

       self.startTimer = function (timeDiff, callback) {
        self.timerId = $interval(function(){
           timeDiff += 1000;
        // This if block will ensure your controller callback called after the value of time diff is updated.
           if(callback) {
              callback(timeDiff)
           }
        },1000);
        return timeDiff;
       }
       self.stopTimer = function () {
         $interval.cancel(self.timerId);
       }

}]);