为什么我们需要调用$ scope。$ apply在dom事件监听器中

时间:2014-12-16 19:10:44

标签: javascript angularjs

为什么单击update-time按钮时值不会更新。

<html ng-app="domC">
    <head>
        <title>Angularjs DOM </title>
    </head>
    <body>       
        <div ng-controller="myController">
            {{data.time}}

            <br/>
            <button ng-click="updateTime()">update time - ng-click</button>
            <button id="updateTimeButton"  >update time</button>
        </div>
        <script src="lib/angular.js"></script>
        <script>
            var module = angular.module("domC", []);
            var myController1 = module.controller("myController", function($scope) {

                $scope.data = { time : new Date() };

                $scope.updateTime = function() {
                    $scope.data.time = new Date();
                }

                document.getElementById("updateTimeButton")
                        .addEventListener('click', function() {
                    console.log("update time clicked");
                    $scope.data.time = new Date();
                });
            });
        </script>
    </body>
</html>

以下这段代码似乎无法将$scope.data.time更新为new Date();

document.getElementById("updateTimeButton")
     .addEventListener('click', function() {
      console.log("update time clicked");
      $scope.data.time = new Date();
});

我有两个questions

  1. 为什么我们需要在我的dom事件监听器中使用$scope.$apply(function(){$scope.data.time});更新值,为什么正常方式不起作用。
  2. 为什么不调用$scope.$digest()而不是$ scope。$ apply()在内部再次调用$ scope。$ digest迭代所有观察者。

2 个答案:

答案 0 :(得分:1)

1)因为你需要通知Angular你的范围已经改变了。如果您使用ng-click,则不需要这样做,这将在内部为您完成。

2)您没有理由调用摘要,正如您所说,apply会在将更改应用到范围后调用它。强制摘要可能会在此时失败,并可能会执行意外操作。

答案 1 :(得分:0)

不要从控制器访问DOM。控制器不应该知道或对视图做出任何假设。

相反,在View中使用ng-click指令来更改范围。巧合的是,您不需要$scope.$apply()

<button id="updateTimeButton" ng-click="updateTime">Update Time</button>

然后,在控制器中:

$scope.updateTime = function(){
   $scope.data.time = new Date();
}

否则,@ lante回答了您关于为何需要$scope.$apply的问题。有时,当您使用执行异步或基于事件的操作的非Angular库时,确实需要它。 不在您的情况下 - 在您的情况下,您需要它,因为您没有遵循最佳实践,如果您继续这样做,您将遇到许多其他问题和头痛。