AngularJS 中的 $digest() 和 $apply()

1. 什么时刻须要工资挪用 $apply()?

AngularJS 只会体贴在 AngularJS 的实行高低文中 发作的数据模型(model)的变化(比方: 转变数据的代码在 $apply() 内里)。AngularJS 内建的指令 也会自动触发 $digest 轮回, 所以任何数据模型(model)的转变也都邑反应到视图中。 然则, 假如变动一个 不在 AngularJS 实行高低文中 的数据模型(model), 就须要工资的挪用 $apply() 来提示 AngularJS 数据发作变化了。

比方, 但运用JavaScript的 setTimeout() 函数来更新一个数据模型的时刻, AngularJS 就没有办法晓得你转变了数据模型。这类情况下, 就须要挪用 $apply() 来触发 $digest 轮回了。相似的, 假如自定义了一个指令, 这个指令设置了一个 DOM 事宜监听器, 变动数据模型的代码在时候处置惩罚函数里, 那末也须要挪用 $apply() 来保证变动能反应出来。

DEMO:

HTML 代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <title>demo</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
    <div ng-app="myApp">
        <div ng-controller="myController">
            Delayed Message: {{message}}
        </div>
    </div>
    <script src="js/angular.js">
    </script>

    <script src="js/apply.js"></script>
</body>

</html>

JS 代码:

var myApp = angular.module('myApp', [])

myApp.controller('myController', ['$scope', '$timeout', function($scope, $timeout) {
    $scope.getMessage = function() {

        // 要领1:
        setTimeout(function() {
            // 把须要写的逻辑放入$apply函数内
            $scope.$apply(function() {
                $scope.message = 'Fetched after 3 seconds'
                console.log('message: ', $scope.message);
            })
        }, 2000)

        // 要领2:

        // $timeout(function() {
        //     $scope.message = 'Fetched after 3 seconds'
        //     console.log('message: ', $scope.message);
        // }, 2000)

        // 要领3:

        // setTimeout(function() {
        //     $scope.message = 'Fetched after 3 seconds'
        //     console.log('message: ', $scope.message);
        //     $scope.$apply() // 这里触发了 $digest轮回
        // }, 2000)
    }

    $scope.getMessage()
}])

注重:

但须要延时的时刻, 尽量的运用 $timeout, 如许, 就不用工资的去挪用 $apply() 了。
在挪用 $apply() 的时刻, 应当老是要传入函数参数, 由于当为 $apply() 传入函数的时刻, 这个函数在挪用的时刻是包含在 try..catch 中, 而且任何发作的非常都能够被 $exceptionHandler 服务所吸收。

2. $digest 轮回要实行多少次呢

$digest 轮回并不只是运转一次。在当前轮回完毕后, 它会再次启动来搜检是不是有数据发作变化, 这被叫做 脏搜检$digest 轮回会一向坚持轮回直到再也没有数据模型发作转变, 或许到达最大的轮回次数(10次)。

注重: $digest 最少会轮回两次纵然监听函数没有变动任何数据模型。它会多运转一次以确保没有数据发作变化。

3. 总结

假如 AngularJS 不能检测到你的变动, 那末就必须工资挪用 $apply()

    原文作者:无名小子
    原文地址: https://segmentfault.com/a/1190000008646451
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞