为什么计数器正确递减但倒计时不是?

时间:2017-11-17 10:17:53

标签: html angularjs math

这是我的角度代码,用于为我的网站定义倒数计时器:



function AlbumCtrl($scope, $timeout) {
  $scope.counter = new Date("Nov 30, 2017 09:00:00").getTime() - new Date().getTime();
  $scope.onTimeout = function() {
    $scope.counter--;
    var distance = $scope.counter;
    $scope.countdown = Math.floor(distance / (1000 * 60 * 60 * 24)) + "d " +
      Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) + "h " +
      Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)) + "m " +
      Math.floor(((distance % (1000 * 60)) / 1000)) + "s ";
    if ($scope.counter > 0) {
      mytimeout = $timeout($scope.onTimeout, 1000);
    } else {
      alert("Time is up!");
    }
  }

  var mytimeout = $timeout($scope.onTimeout, 1000);
}

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <!-- added for a working snippet -->


<!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}} {{countdown}}
  </div>
</body>

</html>
&#13;
&#13;
&#13;

&#39;&#39;&#39;似乎在我的页面上正确递减,但倒计时&#39;保持固定并仅在页面加载或刷新时显示正确的值。例如,随着时间的推移,我得到以下输出:

    1115148833 12d 21h 45m 48s
    1115148745 12d 21h 45m 48s
    1115148693 12d 21h 45m 48s

到底出了什么问题?谢谢你的帮助。

3 个答案:

答案 0 :(得分:0)

https://github.com/johnpapa/angular-styleguide/tree/master/a1

const isFunction = require("lodash.isfunction");
const cloneDeep = require("lodash.clonedeep");

const defaultCompare = require("./defaultCompare");

const bubble = ( array, fnCompare = defaultCompare ) => {

    if( !isFunction(fnCompare) )
        throw new Error("fnCompare must be a function");

    if(!Array.isArray(array))
        throw new Error("array must be an Array");

    if (array.length === 0)
        return [];

    const clonedArray = cloneDeep(array);

    return recursiveSort( clonedArray, clonedArray.length, fnCompare );
};

const recursiveSort = ( array, unsortedLength, fnCompare ) => {
    if( unsortedLength === 1 )
        return array;

    let swapped = false;
    for( let i = 0; i < unsortedLength - 1; i++ ){

        if( fnCompare( array[i], array[i + 1] ) > 0 ){
            const temp = array[i];
            array[i] = array[i + 1];
            array[i + 1] = temp;
            swapped = true;
        }
    }

    //Ensure O(n) if array is already ordered
    if(!swapped)
        return array;

    return recursiveSort( array, unsortedLength - 1, fnCompare );
};

module.exports = bubble;
// Declare a "main" module for the single page application
// second argument to module is an array of dependencies your module
// uses (examples: ui-router ui-bootstrap etc., 'ng' module is assumed as a dependency)
angular.module('myApp', [])


//Defining a service on the module allows you to encapsulate some functionality
//Injecting the angular $timeout service from the 'ng' module and defining
//a new service.  This object gets initialized the first time it's
//referenced and stays alive until the application/page is refreshed.
.service("CountdownService", function($timeout){
  //Define an object to attach properties and functions to and return for
  //use elsewhere in the app
  var countdownService = {};
  
  //Basically the functional code you had already adjusted the
  //seconds to just use %60 since some sort of issue with the existing math
  // %60 should give remainder after dividing by 60 and appears the "distance"
  // was moving at 1 second per second not 1000, so removed the 1000 factors
  countdownService.counter = new Date("Nov 30, 2017 09:00:00").getTime() - new Date().getTime();
  countdownService.onTimeout = function() {
    countdownService.counter--;
    var distance = countdownService.counter;
    
    var newValue = Math.floor(distance / (1000 * 60 * 60 * 24)) + "d " +
      Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) + "h " +
      Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)) + "m " +
      Math.floor((distance % (60)) ) + "s ";
    countdownService.countdown = newValue;
      
      console.log(Math.floor((distance % (60))) + "s ");
    if (countdownService.counter > 0) {
      mytimeout = $timeout(countdownService.onTimeout, 1000);
    } else {
      alert("Time is up!");
    }
  }

  var mytimeout = $timeout(countdownService.onTimeout, 1000);
  return countdownService;
})

//Now the controller just has the new service injected it uses "this"
//instead of scope in the ng-controller we use "controllerAs" syntax
//so we don't need to use the scope (angular 2 hides the scope so good
//to just get used to not using it)
.controller("TestCtrl", function(CountdownService){
  this.CountdownService = CountdownService;
});

答案 1 :(得分:0)

这很有趣。你的Math.floor函数给出了分数的圆形数字,你的分数用计数器变化很小,当计数器到达1095904999时,只有秒数字符串从一个数字减少。所以你无法注意到这个变化,看看你自己:

function AlbumCtrl($scope, $timeout) {
  $scope.counter = new Date("Nov 30, 2017 09:00:00").getTime() - new Date().getTime();
  $scope.onTimeout = function() {
    --$scope.counter;
    var distance = $scope.counter;
   $scope.countdown = $scope.counter/ (1000 * 60 * 60 * 24) + "d " +
  ( $scope.counter% (1000 * 60 * 60 * 24)) / (1000 * 60 * 60) + "h " +
 ( $scope.counter% (1000 * 60 * 60)) / (1000 * 60)+ "m " +
 (( $scope.counter% (1000 * 60)) / 1000) + "s ";
    if ($scope.counter > 0) {
      mytimeout = $timeout($scope.onTimeout, 1000);
    } else {
      alert("Time is up!");
    }
  }

  var mytimeout = $timeout($scope.onTimeout, 1000);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <!-- added for a working snippet -->


<!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}} {{countdown}}
  </div>
</body>

</html>

答案 2 :(得分:0)

出于演示目的(为了简化答案检查的正确性),我将目的地date设置为1天和2小时后:

&#13;
&#13;
function AlbumCtrl($scope, $timeout) {
  var date = new Date();
  date.setHours(date.getHours() + 2);
  date.setDate(date.getDate() + 1);

  $scope.counter = date.getTime() - new Date().getTime();
  $scope.onTimeout = function() {
    $scope.counter = $scope.counter - 1000;
    var ost = $scope.counter;

    function GetPart(koef) {
      koef *= 1000;
      var res = Math.floor(ost / koef);
      ost = ost - res * koef;
      return res;
    }

    var days = GetPart(60 * 60 * 24);
    var hours = GetPart(60 * 60);
    var min = GetPart(60);
    var sec = GetPart(1);

    $scope.countdown = days + "d " + hours + "h " + min + "m " + sec + "s ";

    if ($scope.counter > 0)
      mytimeout = $timeout($scope.onTimeout, 1000);
    else
      alert("Time is up!");
  }

  var mytimeout = $timeout($scope.onTimeout, 1000);
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!-- added for a working snippet -->


<!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">
    {{countdown}}
  </div>
</body>

</html>
&#13;
&#13;
&#13;