为什么直接无法从`AngularJs`中的`controller`调用函数

时间:2015-04-01 11:05:35

标签: javascript angularjs

我正在尝试更新h1元素中的时钟时间。我试图通过设置间隔来调用函数来更新时间,但我无法调用。我找到了apply的解决方案。

但我想了解这背后的逻辑。任何解释我无法打电话的原因,为什么我们应该使用apply方法..?

这是我的工作:



angular.module('Book', [])
.controller('MyController', function ($scope) {
    var updateClock = function() {
        $scope.clock = new Date();
    };
    setInterval(function() {
        updateClock(); //not working when i call from here...?
        //$scope.$apply(updateClock); //it works!
    }, 1000);
    updateClock(); //it works in first time.
});

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="Book">
   <div ng-controller='MyController'>
        <input ng-model="name" type="text" placeholder="Your name">
        <h1>Hello {{ clock }}</h1>
    </div>
</div>
&#13;
&#13;
&#13;

4 个答案:

答案 0 :(得分:2)

简而言之

Angular run $ digest循环在某个特定事件上($ digest循环实际上负责双向数据绑定或脏检查)。事件可能是$ scope函数被调用,$ http返回数据,$ timeout, $ interval等但是如果你使用的不是这个,那么angular就不知道任何东西是变化的(比如说setTimeout是javascript函数)。所以我们明确需要告诉角度,这个角度给我们$ apply。

长期

请参阅此链接http://tutorials.jenkov.com/angularjs/watch-digest-apply.html

答案 1 :(得分:1)

在您的控制器中,使用$interval代替setInterval$interval会自动触发$digest周期。因此,您无需手动调用$scope.$apply。相反,它将由$interval隐式调用。请记住在控制器中注入$interval作为依赖项。

只有当您处于角度背景之外时,才必须使用$scope.$apply。例如,您使用jQuery执行某些操作,然后您必须让角度通过$scope.$apply了解更改,但是当您进入控制器时,它根本不需要

&#13;
&#13;
angular.module('Book', [])
.controller('MyController', function ($scope, $interval) {
    var updateClock = function() {
        $scope.clock = new Date();
    };
    $interval(function() {
        updateClock(); //not working when i call from here...?
        //$scope.$apply(updateClock); //it works!
    }, 1000);
    updateClock(); //it works in first time.
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="Book">
   <div ng-controller='MyController'>
        <input ng-model="name" type="text" placeholder="Your name">
        <h1>Hello {{ clock }}</h1>
    </div>
</div>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

基本上,$scope.apply()正在将更改应用于视图中的范围,因此在您使用apply时它会起作用。

要在没有它的情况下更新范围,您应该使用Angular的$interval服务,而不是setInterval()函数。这基本上调用服务中的$apply()函数,从而更改视图,而无需调用$ apply函数来实现更改。

答案 3 :(得分:0)

以下是plunker

你应该使用$ interval angular service而不是javascript的setInterval。

 $interval(function() {
        updateClock(); //not working when i call from here...?
        //$scope.$apply(updateClock); //it works!
    }, 1000);

现在为什么你需要$ scope.apply()for setInterval是因为你在angular范围之外工作,你需要手动执行摘要循环以在角度范围内验证它。