【问题标题】:AngularJS: determine time elapsed, use to regularly update model and viewAngularJS:确定经过的时间,用于定期更新模型和视图
【发布时间】:2026-01-27 18:05:01
【问题描述】:

上下文

我正在寻找创建一个 web 应用程序,该应用程序将一组数据视为自页面加载以来经过的时间的函数。想想“打开这个网页后你燃烧了多少卡路里”。

我仍在尝试围绕 AngularJS 服务、工厂等进行思考,并且想知道创建可用于定期(每秒)操作和更新 ng-model 的自动更新计时器的最佳方法是什么.

我如何(不成功)想象它会起作用:

我现在有这样的事情:

app.factory('Timer', function($timeout) {
    var time = 0;

    var Timer = function() {
        this.time++;
        this.timeout = $timeout(this.Timer, 1000);
    }
});

并用作

$timeout(function() {
    $scope.someNgModelVarForTheView = Timer.time * $scope.data;
}, 1000);

但是……好吧。在我看来,这很好用。事实上,这一切都发生了,如果我知道正确的方法,我就是在开玩笑......

所以我想,有两个问题:

  • 如何将页面加载后的时间计算为可调用函数?
  • 如何定期(每秒)重新计算数据模型? $timeout 是个好方法吗?

【问题讨论】:

    标签: javascript angularjs timer timeout


    【解决方案1】:

    如果你想拥有自己的服务,你可以这样做:

    .factory('MyTimer', function($interval){
        return function(delay){
            var initialMs= (new Date()).getTime();
            var result = {totalMilliseconds:0, counts:0};                
            $interval(function() {
                result.totalMilliseconds = (new Date()).getTime() - initialMs;
                result.counts++;
            }, delay);
            return result;
        };
     })    
    

    你可以这样使用它:

    .controller('testController', function($scope, MyTimer){    
        $scope.t = MyTimer(1000);
    });
    

    在你的 html 中你可以这样做:

    <div ng-app="app" ng-controller="testController">
       Total Ms: {{t.totalMilliseconds}}
       Counts: {{t.counts}}
    </div>
    

    Example

    【讨论】:

    • 这正是我最初的想法,非常感谢!不过,问题是,将此功能作为自己的服务有什么好处,而不仅仅是一个未包装的 $interval 函数(根据我下面的回答?)
    • 最明显的优点是你可以在任何你想要的地方很容易地重复使用它,即使它是一个完全不同的项目,另一个优点是你可以独立测试它,这也很好,而且,看看你需要在你的控制器中没有这个“服务包装器”的代码,在你拥有它之后......性能方面是一样的,但我认为你的代码会更容易维护。
    【解决方案2】:

    呃,我最终把我的想法过于复杂化了。这成功了:

    var delay = 1000; // 1 sec
    $scope.currentTime = 0;
    
    $interval(function() {
      $scope.currentTime += delay;
      $scope.someData *= $scope.currentTime;
    }, delay);
    

    【讨论】:

    • 请记住,间隔函数不会在您在“延迟”参数中设置的确切毫秒数内执行,因此您建议的这种方法不会完全准确,这几乎不会引起注意,但我仍然认为你应该让你知道。
    • 我确实注意到它总是在 1002-1008 左右而不是 1000 左右,但我并不太大惊小怪,而且我觉得修复起来比考虑应用程序更值得: P
    • 当然!另外,请看一下我的回答,毕竟拥有该服务可能非常有用,因为它会使您在控制器中的代码更清洁且更易于维护。谢谢!