`
云上太阳
  • 浏览: 128501 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

angularjs框架$apply,$digest和$watch实例讲解

阅读更多

angularjs框架$apply,$digest和$watch理解

                                                                                    ——我一直不太信任自己的记忆力,所以我把它们都写下来

 

一、$aplly()添加普通js代码到angular框架

代码演示前先看看$apply方法的作用:$apply方法可以在angularjs框架之外执行angularJs表达式。现在不明白没关系,先看代码

<p ng-controller="myCtrl">{{message}}</p>
<script type="text/javascript">
        function myCtrl($scope) {
          $scope.message ="等待3秒";    
          setTimeout(function () {
             console.log('message已刷新');
            $scope.message ="等了3秒";
          }, 3000); 
        }
</script>

   运行上面的代码,显示“等待3秒”。但是过了3秒之后 message的内容并没有变成“等了3秒”。控制台却打印出“message已刷新”,所以 $scope.message ="等了3秒"; 这句代码已经执行了。 很显然数据的更新并没有被angular觉察到。看看另一段代码

<p ng-controller="myCtrl">{{message}}</p>

<script type="text/javascript">
        function myCtrl($scope) {
          $scope.message ="等待3秒";    
          setTimeout(function () {
             console.log('message已刷新');
             $scope.$apply(function () {
              $scope.message ="等了3秒";
             });
          }, 3000); 
        }
</script>

  代码可以看得出我们把刷新数据的内容加到$apply方法内部了。这次运行代码3秒过后message的值变成了 “等了3秒”。

    回到开头我们再看看$apply方法的作用:$apply方法可以在angularjs框架之外执行angularJs表达式。很明显,我们更新message的值在myCtrl函数中,而不是在angular作用域下面。$apply在与其他js代码集成时很有用。

 

二、$digest 循环检测

     在第一段代码$scope.message ="等了3秒"; 后面增加一行代码$scope.$degist()或者$scope.$apply();也能实现我们的目的。$digetst循环检测view绑定的数据是否变化,如果变化了则更新它。其实调用$apply方法接下来也是$digest检测绑定数据的变化,然后更新view。是不是一头雾水?这是angularjs初学者的第一个关隘,很多初学者对angularjs的数据绑定是如何工作的相当疑惑。一开始我也没有深究,为了便于记忆,理解成onkeydown事件的处理。

 

三、$watch队列

    按道理来讲应该先讲$watch,然后是$digest,接着$apply。可笔者是从初学者的实用角度出发,毕竟$apply更贴近于实际应用。

     在angular框架,每次绑定数据到view时都会向$watch队列里添加一个$watch,对数据变化的检测就是$watch。看个代码

用户:<input type="text" ng-model="name"/>密码:<input type="password" ng-model="pass"/>

在这里我们有个$scope.name,他被绑定在了第一个输入框上,还有个$scope.pass,它被绑定在了第二个输入框上,然后我们在$watch 队列里面加入两个$watch

再看一段代码

app.controller('MainCtrl',function($scope){
  $scope.foo ="Foo";
  $scope.world ="World";});

hello{{World}}

      这里虽然我们在Controller中给$scope添加了两个东西,但是view层我们只绑定了一个{{World}}  ,所以只生成了一个$watch。      

看一个比较复杂的例子,以便更好理解$watch      

app.controller('MainCtrl',function($scope){
  $scope.people =[...];//假设有10个元素});

index.html

<ul><ling-repeat="person in people">
      {{person.name}} - {{person.age}}
  </li></ul>

    这里又生成了多少个$watch呢?每个person有两个(一个name,一个age),然后ng-repeat又有一个,循环了十次,因此10个person一共是(2 * 10) +1,也就是说有21个$watch。 因此,每一个绑定到了UI上的数据都会生成一个$watch。对,那这些$watch是什么时候生成的呢? 当我们的模版加载完毕时,也就是在linking阶段(Angular分为compile阶段和linking阶段---译者注),Angular解释器会寻找每个directive,然后生成每个需要的$watch。听起来不错哈,但是,然后呢?

    接下来当然是$degist循环遍历$watch队列,检查是否有数据发生变化,当$degist循环完毕,如果有改变则更新view。

 英语好的看看这篇文章,保证受益匪浅。

http://angular-tips.com/blog/2013/08/watch-how-the-apply-runs-a-digest/

 

4
1
分享到:
评论

相关推荐

    angularjs 中$apply,$digest,$watch详解

    主要介绍了angularjs 中$apply,$digest,$watch详解的相关资料,需要的朋友可以参考下

    AngularJS报错$apply already in progress的解决方法分析

    如果我们使用了AngularJS中的$scope.$apply()或者$scope.$digest(),我们很可能会遇到类似下面的错误,虽然这个错误没有太大影响,但是在日志中看起来还是很不爽的,日志中记录的异常或者错误,就应该是需要关注和...

    AngularJS双向数据绑定原理之$watch、$apply和$digest的应用

    主要介绍了AngularJS双向数据绑定原理之$watch、$apply和$digest的应用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    理解$watch ,$apply 和 $digest --- 理解数据绑定过程

    NULL 博文链接:https://bijian1013.iteye.com/blog/2392155

    AngularJS中的$watch(),$digest()和$apply()区分

    AngularJS $scope里面的$watch(),$digest()和$apply()是AngularJS的核心函数,学习AngularJS必须理解这几个函数。 在绑定$scope中的变量到view的时候,AngularJS自动在内部创建一个”Watch”。”Watch”用于监听...

    Angularjs中的$apply及优化使用详解

    今天,我们要聊得是Angularjs中的小明星$apply。当我们数据更新了,但是view层却没反应时,总能听到有人说,用apply吧,然后,懵懂无知的我们,在赋值代码后面加了$scope.$apply() ,然后就惊喜的发现。噢,真的更新...

    浅谈angular.js中实现双向绑定的方法$watch $digest $apply

    Angular用户都想知道数据绑定是怎么实现的。你可能会看到各种各样的词汇:$watch,$apply,$digest它们是如何工作的呢?这里我想回答这些问题,其实它们在官方的文档里都已经回答了,但是我还是想把它们结合在一起来讲

    全面解析Angular中$Apply()及$Digest()的区别

    $apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑。而为了了解AngularJS的工作方式,首先需要了解$apply()和$digest()是如何工作的。这篇文章旨在解释$apply()和$digest()是什么,以及在...

    angularjs-tips:在AngularJS框架中做事的提示和技巧

    注意:如果您确定自己不在角度范围内,最好在代码后调用$scope.$digest而不是使用$scope.$apply因为$apply将在$rootScope上调用$digest ,这要重得多。 2.从您的控制器检查表格是否脏了或无效。 // `formName` is...

    Angular.js中$apply()和$digest()的深入理解

    相信大家都知道$digest()和$apply()是AngularJS中的两个核心并且有时候容易引人误解的部分。我们需要深入理解这两者是如何运作的,从而才能理解AngularJS本身是如何运作的。本文的目的就是介绍$digest()和$apply()是...

    深入理解AngularJs-scope的脏检查(一)

    进入正文前的说明:本文中的示例代码并非AngularJs源码,而是来自书籍&lt;&lt;Build&gt;&gt;, 这本书的作者仅依赖jquery和...1.dirty-checking(脏检测)核心机制,主要包括:$watch 和 $digest; 2.几种不同的触发$digest循环

    ngPerf:Angular 性能提示工具

    性能 AngularJS 性能提示工具。 背景 尽可能使用一次性绑定 $scope.$apply()将从$rootScope传播到所有作用域 ... 这意味着当exp评估变得稳定时,AngularJS 将自动取消监视此exp并销毁其上的$watch 。

    Bookmarklet-Get-Watch-Count:我计算当前 AngularJS 页面中活动 $watch() 绑定的数量

    每个 $watch() 绑定代表 AngularJS 在每个 $digest 阶段必须执行的处理开销。 通过减少观察者的数量,您可以提高 AngularJS 应用程序的性能。 请从获取书签。 bookmarklet 使用document.querySelectorAll() ,因此...

    精通AngularJS part1

    13AngularJS和其他框架38 jQuery与AngularJS39 苹果与橙子40 窥视未来41 14总结41 第2章构建与测试43 21介绍示例应用44 熟悉问题领域44 技术栈45 持久化存储46 MongoLab46 服务器端环境47 第三方...

Global site tag (gtag.js) - Google Analytics