$ Scope变量不在HTML中更新,尽管在控制器中不断更新

时间:2016-05-11 14:00:53

标签: javascript angularjs angularjs-scope counter

代码发布在codepen上: http://codepen.io/karlsaks/pen/KzEyLR

问题是我正在构建一个应该显示数字减少的计数器,因为angular有2路绑定,我确信它们在应用程序的控制器端更新(可以通过访问控制台看到)

我真的没有选择,any1可以帮忙吗?

<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <title>Counter</title>
  <link rel="stylesheet" type="text/css" href="./style.css">
<!--   <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script> -->
  <script type="text/javascript" src="angular.min.js"></script>
  <script type="text/javascript" src="app.js"></script>
</head>
<body ng-controller="myCtrl">
  <div id="inputBox">  
    <input id="userInput">
    <button type="button" onclick="submit()">Submit</button>
  </div>
  <br>
  <div id="clockdiv">
    <div>
      <span>{{days}}</span>
      <div class="smalltext">Days</div>
    </div>
    <div>
      <span>{{hours}}</span>
      <div class="smalltext">Hours</div>
    </div>
    <div>
      <span>{{minutes}}</span>
      <div class="smalltext">Minutes</div>
    </div>
    <div>
      <span>{{seconds}}</span>
      <div class="smalltext">Seconds</div>
    </div>
  </div>
</body>
</html>


    angular
        .module("myApp", [])
        .controller("myCtrl", ['$scope', function ($scope) { 
            console.log("Controller loaded");
            var vm = this;
            $scope.getTimeRemaining = function(endtime) {
            $scope.t = Date.parse(endtime) - Date.parse(new Date());
            $scope.s = Math.floor(($scope.t / 1000) % 60);
            $scope.m = Math.floor(($scope.t / 1000 / 60) % 60);
            $scope.h = Math.floor(($scope.t / (1000 * 60 * 60)) % 24);
            $scope.d = Math.floor($scope.t / (1000 * 60 * 60 * 24));

            console.log("time remaining :" + $scope.d + " " + $scope.h + " " + $scope.m + " " + $scope.s);
            }

            $scope.initializeClock = function(endtime) {
                var updateClock = function() { 
                    $scope.getTimeRemaining(endtime);
                    $scope.days = $scope.d;
                    $scope.hours = $scope.h;
                    $scope.minutes = $scope.m;
                    $scope.seconds = $scope.s;
                    console.log("time remaining :" + $scope.days + " " + $scope.hours + " " + $scope.minutes + " " + $scope.seconds);
                    if ($scope.t <= 0 ){
                        clearInterval(timeinterval)
                    }   
                }

                updateClock();
                var timeinterval = setInterval(updateClock, 1000);
            }


            $scope.initializeClock(new Date("May 12,2016 11:00:00"))



        }])

2 个答案:

答案 0 :(得分:0)

您必须使用角度特定$interval实施,否则您必须在每个间隔周期中手动运行$scope.$apply,以便消除$ scope更改

我的首选方法:使用$interval,因为它会自动使用$scope.$apply

编辑:似乎$scope.$apply在角度版本1.5中不再可用(它在1.4中)。所以我认为现在必须使用$ interval

答案 1 :(得分:0)

上面的devnull69回答你必须使用$ interval服务,使用setTimeout或setInterval使得进程不知道AngularJS。所以你在他们之后手动通知angularJS usning $scope.$apply()或使用他们的服务$ interval / $ timeout已经在幕后做了。

因此,在您的情况下,我会建议以下实施:

1 - 插入/插入控制器上的$ interval服务

.controller("myCtrl", ['$scope', function ($scope, $interval) { 

2 - 改变间隔实现(使用$ scope变量,所以你不要松开对timeinterval变量的引用。

            if ($scope.t <= 0 ){
                    $interval.cancel($scope.timeinterval)
                }   
            }

            updateClock();
            $scope.timeinterval = $interval(updateClock, 1000);