写AngularJS代码时会时常发现,有时候明明数据模型更新了但是页面视图层并没有更新,然后只要在代码里加上一句$scope.$apply(),视图就更新了。以前总是不清楚什么时候该用,现在清晰了,记录一下。

其实总结一句就是:DOM监听事件处理程序中的代码,外部的回调函数(例如setTimeout(),setInterval())中的代码等不在Angular执行上下文中的代码,如果有修改到Angular数据模型时,则必须由我们手动调用$apply()来获得视图层的更新。$apply方法将会调用一个digest循环来更新整个视图层。

$apply()必须在该调用的时候调用,在我们使用AngularJS的提供的指令或服务,如ng-click$timeout等来处理数据模型时,Angluar会自动调用$scope.$apply(),如果再手动调用是会报错的。

例如,假设我们不使用Angular提供的$timeout服务,而使用原生的setTimeout(),则这个时候必须用$apply()才能使得数据更新。

比较好的写法是将涉及数据模型改变的代码写在$scope.$apply()里面,而不是执行完代码后再调用一次$scope.$apply()。传递给$scope.$apply()执行,Angular才会对这段代码做异常处理。

angular.module('myModule', []).controller('MyController', function($scope) {
    $scope.updateTime = function() {
        setTimeout(function() {
            $scope.$apply(function() {
                $scope.timestamp = new Date().getTime();
            });
        }, 1000);
    };
});