AngularJS 制作一个简单的倒计时。

50

我想使用AngularJS制作倒计时。这是我的代码:

HTML文件

<div ng-app ng-controller = "countController"> {{countDown}} <div>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

JavaScript 文件

function countController($scope){
    $scope.countDown = 10;    
    var timer = setInterval(function(){$scope.countDown--; console.log($scope.countDown)},1000);  
}​​

在 console.log 中它可以工作,我有一个倒计时,但在 {{countdown}} 刷新中它不起作用,请你帮帮我,谢谢!


更为简便的方法是使用预先构建的指令:http://siddii.github.io/angular-timer/ - Brett
10个回答

60
请查看这个例子。这是一个简单的计数器示例!我认为您可以轻松修改它来创建一个倒计时。 http://jsfiddle.net/ganarajpr/LQGE2/

JavaScript 代码:

function AlbumCtrl($scope,$timeout) {
    $scope.counter = 0;
    $scope.onTimeout = function(){
        $scope.counter++;
        mytimeout = $timeout($scope.onTimeout,1000);
    }
    var mytimeout = $timeout($scope.onTimeout,1000);

    $scope.stop = function(){
        $timeout.cancel(mytimeout);
    }
}

HTML标记:

<!doctype html>
<html ng-app>
<head>
    <script src="http://code.angularjs.org/angular-1.0.0rc11.min.js"></script>
    <script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
</head>
<body>
<div ng-controller="AlbumCtrl">
    {{counter}}
    <button ng-click="stop()">Stop</button>    
</div>
</body>
</html>

7
这是一个倒计时的修改版本:http://jsfiddle.net/dpeaep/LQGE2/1/ - Daniel
2
很好,我使用了$interval而不是$timeout。 - Andres
你会如何停止时钟? - CodyBugstein
同意@Andres的观点 - 我认为$interval是最好的选择。这是我最终用于angularjs计时器实现的答案 - jaycer

25

从版本1.3开始,模块ng中有一个服务:$interval

function countController($scope, $interval){
    $scope.countDown = 10;    
    $interval(function(){console.log($scope.countDown--)},1000,0);
}​​

请谨慎使用:

注意:该服务创建的时间间隔必须在使用完成后显式销毁。特别是当控制器作用域或指令元素被销毁时,它们不会自动销毁。您应该考虑这一点,并确保在适当的时刻始终取消时间间隔。有关如何以及何时执行此操作的更多详细信息,请参见下面的示例。

来自:Angular 官方文档


谢谢。对于其他想知道的人,这不仅限于1.3版本:http://code.angularjs.org/1.2.12/docs/api/ng.$interval - Hakan B.

9
你在使用Angular框架外部执行一个angular表达式时,应该使用$scope.$apply()
function countController($scope){
    $scope.countDown = 10;    
    var timer = setInterval(function(){
        $scope.countDown--;
        $scope.$apply();
        console.log($scope.countDown);
    }, 1000);  
}

http://jsfiddle.net/andreev_artem/48Fm2/


17
在Angular中直接使用setTimeOut或setInterval并不是一个好的实践。你应该使用$timeout服务。 - ganaraj
5
这取决于任务。实用性胜过纯粹性。 - Artem Andreev
4
AngularJS 中有一个名为 $timeout 的服务,它会自动调用 $apply。 - pkozlowski.opensource
1
@pkozlowski.opensource 谢谢,你没有说任何新的东西。我能够阅读答案和评论 :) 我认为有两个答案是很好的。一个解释为什么代码不起作用以及如何使其起作用。另一个则解释了如何以更angular的方式完成它。 - Artem Andreev
你的答案更好。你使用了间隔,这对于计数器来说更加合适。 - guy mograbi
@ ganaraj,您能展示使用$timeout服务实现相同效果的代码吗? - Dipesh KC

7
我更新了ganaraj先生的答案,增加了停止和继续功能,并添加了angularJS过滤器来格式化倒计时器。 这里是在jsFiddle上的代码 控制器代码
'use strict';
var myApp = angular.module('myApp', []);
myApp.controller('AlbumCtrl', function($scope,$timeout) {
    $scope.counter = 0;
    $scope.stopped = false;
    $scope.buttonText='Stop';
    $scope.onTimeout = function(){
        $scope.counter++;
        mytimeout = $timeout($scope.onTimeout,1000);
    }
    var mytimeout = $timeout($scope.onTimeout,1000);
    $scope.takeAction = function(){
        if(!$scope.stopped){
            $timeout.cancel(mytimeout);
            $scope.buttonText='Resume';
        }
        else
        {
            mytimeout = $timeout($scope.onTimeout,1000);
            $scope.buttonText='Stop';
        }
            $scope.stopped=!$scope.stopped;
    }   
});

这段代码是从stackoverflow网站的RobG改编而来的。

myApp.filter('formatTimer', function() {
  return function(input)
    {
        function z(n) {return (n<10? '0' : '') + n;}
        var seconds = input % 60;
        var minutes = Math.floor(input / 60);
        var hours = Math.floor(minutes / 60);
        return (z(hours) +':'+z(minutes)+':'+z(seconds));
    };
});

我认为格式计时器没有返回正确的答案。比如说输入是7200,它会返回02:120:00。我认为你应该先计算小时来格式化计时器。 - Bobby Stenly

1

这可能有助于“如何在AngularJS中编写倒计时表的代码”

步骤1:HTML代码示例

<div ng-app ng-controller="ExampleCtrl">
    <div ng-show="countDown_text > 0">Your password is expired in 180 Seconds.</div>
    <div ng-show="countDown_text > 0">Seconds left {{countDown_text}}</div>
    <div ng-show="countDown_text == 0">Your password is expired!.</div>
</div>

步骤2:AngularJS 代码示例

function ExampleCtrl($scope, $timeout) {
  var countDowner, countDown = 10;
  countDowner = function() {
    if (countDown < 0) {
      $("#warning").fadeOut(2000);
      countDown = 0;
      return; // quit
    } else {
      $scope.countDown_text = countDown; // update scope
      countDown--; // -1
      $timeout(countDowner, 1000); // loop it again
    }
  };

  $scope.countDown_text = countDown;
  countDowner()
}

下面是使用AngularJs实现倒计时的完整示例。

<!DOCTYPE html>
<html>

<head>
  <title>AngularJS Example - Single Timer Example</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
  <script>
    function ExampleCtrl($scope, $timeout) {
      var countDowner, countDown = 10;
      countDowner = function() {
        if (countDown < 0) {
          $("#warning").fadeOut(2000);
          countDown = 0;
          return; // quit
        } else {
          $scope.countDown_text = countDown; // update scope
          countDown--; // -1
          $timeout(countDowner, 1000); // loop it again
        }
      };

      $scope.countDown_text = countDown;
      countDowner()
    }
  </script>
</head>

<body>
  <div ng-app ng-controller="ExampleCtrl">
    <div ng-show="countDown_text > 0">Your password is expired in 180 Seconds.</div>
    <div ng-show="countDown_text > 0">Seconds left {{countDown_text}}</div>
    <div ng-show="countDown_text == 0">Your password is expired!.</div>
  </div>
</body>

</html>

1

我所做的方式,它有效!

  • *适用于 Angular 版本 1.5.8 及以上。

Angular 代码

var app = angular.module('counter', []);

app.controller('MainCtrl', function($scope, $interval) {
  var decrementCountdown = function() {
    $scope.countdown -= 1;
    if ($scope.countdown < 1) {
      $scope.message = "timed out";
    }
  };
  var startCountDown = function() {
    $interval(decrementCountdown, 1000, $scope.countdown)
  };
  $scope.countdown = 100;
  startCountDown();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.10/angular.min.js"></script>



<body ng-app="counter" ng-controller="MainCtrl">
  {{countdown}} {{message}}
</body>


1
您可能没有正确声明模块,或者在模块声明之前放置了函数(安全规则是在页面加载完成后将angular模块放在body之后)。由于您正在使用angularjs,因此应该使用$interval(angularjs相当于windows服务的setInterval)。
这里是一个可行的解决方案:

angular.module('count', [])
  .controller('countController', function($scope, $interval) {
    $scope.countDown = 10;
    $interval(function() {
      console.log($scope.countDown--);
    }, 1000, $scope.countDown);
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.1/angular.min.js"></script>


<body>
  <div ng-app="count" ng-controller="countController"> {{countDown}} </div>
</body>

注意:在HTML视图中它停在0,但在console.log中它停在1,你能想出为什么吗? ;)

1
如果您在此处查看$interval的用法https://docs.angularjs.org/api/ng/service/$interval,代码就非常简单明了。 $interval启动一个服务,每秒减少countDown(即1000 = 1秒),第三个参数告诉它要执行10次(因为$scope.countDown的初始值为10)。 - Tan Tran

0
function timerCtrl ($scope,$interval) {
    $scope.seconds = 0;
    var timer = $interval(function(){
        $scope.seconds++;
        $scope.$apply();
        console.log($scope.countDown);
    }, 1000);
}

0
$scope.countDown = 30;
var timer;
$scope.countTimer = function () {
    var time = $timeout(function () {
         timer = setInterval(function () {
             if ($scope.countDown > 0) {
                 $scope.countDown--;
            } else {
                clearInterval(timer);
                $window.location.href = '/Logoff';
            }
            $scope.$apply();
        }, 1000);
    }, 0);
}

$scope.stop= function () {
    clearInterval(timer);
    
}

在HTML中:

<button type="submit" ng-click="countTimer()">Start</button>
<button type="submit" ng-click="stop()">Clear</button>
                 
                
              

0
var timer_seconds_counter = 120;
$scope.countDown = function() {
      timer_seconds_counter--;
      timer_object = $timeout($scope.countDown, 1000);
      $scope.timer = parseInt(timer_seconds_counter / 60) ? parseInt(timer_seconds_counter / 60) : '00';
      if ((timer_seconds_counter % 60) < 10) {
        $scope.timer += ':' + ((timer_seconds_counter % 60) ? '0' + (timer_seconds_counter % 60) : '00');
      } else {
        $scope.timer += ':' + ((timer_seconds_counter % 60) ? (timer_seconds_counter % 60) : '00');
      }
      $scope.timer += ' minutes'
      if (timer_seconds_counter === 0) {
        timer_seconds_counter = 30;
        $timeout.cancel(timer_object);
        $scope.timer = '2:00 minutes';
      }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接