资讯专栏INFORMATION COLUMN

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

alanoddsoff / 880人阅读

摘要:但是如果更改一个不在执行上下文中的数据模型就需要人为的调用来提醒数据发生变化了。在当前循环结束后它会再次启动来检查是否有数据发生变化这被叫做脏检查。它会多运行一次以确保没有数据发生变化。

1. 什么时候需要人为调用 $apply()?

AngularJS 只会关心在 AngularJS 的执行上下文中 发生的数据模型(model)的变化(比如: 改变数据的代码在 $apply() 里面)。AngularJS 内建的指令 也会自动触发 $digest 循环, 所以任何数据模型(model)的改变也都会反映到视图中。 但是, 如果更改一个 不在 AngularJS 执行上下文中 的数据模型(model), 就需要人为的调用 $apply() 来提醒 AngularJS 数据发生变化了。

例如, 但使用JavaScript的 setTimeout() 函数来更新一个数据模型的时候, AngularJS 就没有办法知道你改变了数据模型。这种情况下, 就需要调用 $apply() 来触发 $digest 循环了。类似的, 如果自定义了一个指令, 这个指令设置了一个 DOM 事件监听器, 更改数据模型的代码在时间处理函数里, 那么也需要调用 $apply() 来保证更改能反映出来。

DEMO:

HTML 代码:





    demo
    
    



    
Delayed Message: {{message}}

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://www.ucloud.cn/yun/86905.html

相关文章

  • angular性能优化心得

    摘要:本文针对的读者具备性能优化的相关知识雅虎条性能优化原则高性能网站建设指南等拥有实战经验。这种机制能减少浏览器次数,从而提高性能。仅会检查该和它的子,当你确定当前操作仅影响它们时,用可以稍微提升性能。 搬运自: http://atian25.github.io/2014/05/09/angular-performace/ 不知不觉,在项目中用angular已经半年多了,踩了很多坑...

    guqiu 评论0 收藏0
  • 总结的AngularJS1版本的一些面试问题

    摘要:综上所述两者是出于不同的目的被创建的,解决的也是不同的问题。检测模型变化的过程称为循环。由指令注册的事件处理函数执行。该回调函数会更新插值表达式所在的属性。模块主要关系脚本加载问题。 AngularJS面试题 1.与jQuery的比较 jQuery js函数库 封装简化dom操作 使用jquery的思想是:我拥有一个DOM元素并且想让它去做某件事。也就是命令式编程思想。 angula...

    defcon 评论0 收藏0
  • angularJS开发的注意事项汇总

    摘要:作为一个应该具有经常总结反思的习惯如果不能及时总结可能就会忘记自己踩过的很多坑然后会导致同一个坑踩很多次所以我打算把这些都记录下来以方便是对自己的重复记忆避免无效的另一方面可以希望可以给遇到相似问题的同僚们一些收获手动触发脏检查在开发过程中 作为一个coder,应该具有经常总结反思的习惯,如果不能及时总结,可能就会忘记自己踩过的很多坑,然后会导致同一个坑踩很多次,所以我打算把这些都记录...

    Null 评论0 收藏0
  • 关于angularJs中使用$.ajax的注意点

    摘要:的特色是双向绑定,复杂点说,有一个脏值检测系统,主要包括和触发里面有一个玩意叫被认为是使与第三方库混合使用最标准的方式。处理完成之后加一个即可,这个方法还适用于等但是我依旧建议在能不使用第三方库的时候就不要使用。 从技术上来讲,angular 与 jquery混用,是一件不太合适的,但是为什么这个话题争论至今依旧仁者见仁智者见智,除了便捷度,还有可能就是jquery有些地方确实比ang...

    wayneli 评论0 收藏0

发表评论

0条评论

alanoddsoff

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<