AngularJS中的$watch(),$digest()和$apply()区分  更新时间:2016年04月04日 09:02:11   作者:liangzi4000   这篇文章主要介绍了AngularJS中的$watch(),$digest()和$apply()区分,感兴趣的朋友可以参考一下 AngularJS $scope里面的$watch(),$digest()和$apply()是AngularJS的核心函数,学习AngularJS必须理解这几个函数。 在绑定$scope中的变量到view的时候,AngularJS自动在内部创建一个”Watch”。”Watch”用于监听AngularJS scope中变量的改变。可以通过调用$scope.$watch()这个方法来创建”Watch”。 $scope.$digest()函数会循环访问所有的watches,并检测其所监听的$scope中的变量是否改变。如果变量发生改变,会调用该变量对应的监听函数。监听函数可以实现很多操作,比如让html里面的text文本显示最新的变量值。可见,$scope.$digest是可以触发数据绑定更新的。 大部分情况下,AngualrJS会自动调用$scope.$watch()和$scope.$digest()函数,但是在某些情况下,我们需要手动调用他们,因此,有必要了解他们是怎么工作的。 $scope.$apply()这个函数会先执行一些代码,之后在调用$scope.$digest()。所有的watches会被检测一次,相应的监听函数也会被执行。$scope.$apply()在AngularJS与其它javascript代码集成时是很有用的。 接下来我们具体的讲解下$watch(), $digest() 和 $apply()。 $watch() $watch(watchExpression, listener, [objectEquality]) watchExpression:监听对象,可以是string或者function(scope){} listener:监听对象发生改变时执行的回调函数function(newVal,oldVal,scope){} objectEquality:是否深度监听,如果设置为true,它告诉Angular检查所监控的对象中每一个属性的变化。如果你希望监控数组的个别元素或者对象的属性而不是一个普通的值, 那么你应该使用它。(默认值:false) $digest() 检测当前scope以及子scope中所有的watches,因为监听函数会在执行过程中修改model(scope中的变量),$digest()会一直被调用直到model没有再变。当调用超过10次时,$digest()会抛出一个异常”Maximum iteration limit exceeded’,以此来防止程序进入一个死循环。 $apply() $apply([exp]) exp:string或者function(scope){} $apply()生命周期伪代码示意图如下 function $apply(expr) { try { return $eval(expr); } catch (e) { $exceptionHandler(e); } finally { $root.$digest(); } } Example 下面我们通过一个例子来说明$watch,$digest和$apply。 {{data.time}} update time – ng-click update time 这段代码会绑定$scope.data.time到HTML中显示出来,同时这个绑定会自动创建一个watch来监听$scope.date.time的变化。此外,这里还有2个按钮,第一个按钮是通过ng-click Directive来调用$scope.updateTime方法,之后AngularJS会自动执行$scope.$digest()使最新的时间显示到HTML中。第二个按钮是通过javascript代码添加一个点击事件,以此来更新HTML中的时间。但是第二个按钮是不能工作的,它的解决办法是在点击事件的最后手动的去调用$scope.$digest()方法,如下: document.getElementById(“updateTimeButton”) .addEventListener(‘click’, function() { console.log(“update time clicked”); $scope.data.time = new Date(); $scope.$digest(); }); 另外一个解决办法是调用$scope.$apply(),如下: document.getElementById(“updateTimeButton”) .addEventListener(‘click’, function() { $scope.$apply(function(){ console.log(“update time clicked”); $scope.data.time = new Date(); } ); }); 以上就是本文的全部内容,希望对大家的学习有所帮助。 您可能感兴趣的文章: angularJS中$apply()方法详解 浅谈angular.js中实现双向绑定的方法$watch $digest $apply 全面解析Angular中$Apply()及$Digest()的区别 AngularJS中$apply方法和$watch方法用法总结 AngularJS报错$apply already in progress的解决方法分析 Angular项目中$scope.$apply()方法的使用详解 angularjs 中$apply,$digest,$watch详解 Angular.js中$apply()和$digest()的深入理解 AngularJS双向数据绑定原理之$watch、$apply和$digest的应用 Angularjs中的$apply及优化使用详解 AngularJS $watch() $digest() $apply() 相关文章 Angularjs渲染的 using 指令的星级评分系统示例 本篇文章主要介绍了Angularjs渲染的 using 指令的星级评分系统示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 2017-11-11 es6+angular1.X+webpack 实现按路由功能打包项目的示例 本篇文章主要介绍了es6+angular1.X+webpack 实现按路由功能打包项目的示例,具有一定的参考价值,有需要的可以了解一下 2017-08-08 angularjs实现简单的购物车功能 这篇文章主要为大家详细介绍了angularjs实现简单的购物车功能 ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 2017-09-09 浅谈对Angular中的生命周期钩子的理解 本篇文章主要介绍了Angular中的生命周期钩子的理解,详细的介绍了生命周期钩子和主要的生命周期钩子,有兴趣的可以了解一下 2017-07-07 利用Angularjs和原生JS分别实现动态效果的输入框 现在的很多网站都将输入框做成了动态的效果,这样对于用户体检来说非常好,这篇文章分别用Angularjs和原生JS两种方法来实现动态效果的输入框,具有一定的参考价值,有需要的小伙伴们可以来参考借鉴。 2016-09-09 protractor的安装与基本使用教程 这篇文章主要给大家介绍了关于protractor安装与基本使用的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。 2017-07-07 AngularJS深入探讨scope,继承结构,事件系统和生命周期 这篇文章主要介绍了AngularJS的scope,继承结构,事件系统和生命周期,较为详细的分析了scope的作用域、层次结构、继承及生命周期相关概念与使用技巧,需要的朋友可以参考下 2016-11-11 Angular实现点击按钮后在上方显示输入内容的方法 这篇文章主要介绍了Angular实现点击按钮后在上方显示输入内容的方法,涉及AngularJS事件响应及页面元素属性动态设置相关操作技巧,需要的朋友可以参考下 2017-12-12 深究AngularJS中$sce的使用 本篇文章主要介绍了深究AngularJS中$sce的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 2017-06-06 angularjs http与后台交互的实现示例 这篇文章主要介绍了angularjs http与后台交互的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 2018-12-12 最新评论

AngularJS $scope里面的$watch(),$digest()和$apply()是AngularJS的核心函数,学习AngularJS必须理解这几个函数。

在绑定$scope中的变量到view的时候,AngularJS自动在内部创建一个”Watch”。”Watch”用于监听AngularJS scope中变量的改变。可以通过调用$scope.$watch()这个方法来创建”Watch”。

$scope.$digest()函数会循环访问所有的watches,并检测其所监听的$scope中的变量是否改变。如果变量发生改变,会调用该变量对应的监听函数。监听函数可以实现很多操作,比如让html里面的text文本显示最新的变量值。可见,$scope.$digest是可以触发数据绑定更新的。

大部分情况下,AngualrJS会自动调用$scope.$watch()和$scope.$digest()函数,但是在某些情况下,我们需要手动调用他们,因此,有必要了解他们是怎么工作的。

$scope.$apply()这个函数会先执行一些代码,之后在调用$scope.$digest()。所有的watches会被检测一次,相应的监听函数也会被执行。$scope.$apply()在AngularJS与其它javascript代码集成时是很有用的。

接下来我们具体的讲解下$watch(), $digest() 和 $apply()。

$watch()
$watch(watchExpression, listener, [objectEquality])

watchExpression:监听对象,可以是string或者function(scope){}

listener:监听对象发生改变时执行的回调函数function(newVal,oldVal,scope){}

objectEquality:是否深度监听,如果设置为true,它告诉Angular检查所监控的对象中每一个属性的变化。如果你希望监控数组的个别元素或者对象的属性而不是一个普通的值, 那么你应该使用它。(默认值:false)

$digest()
检测当前scope以及子scope中所有的watches,因为监听函数会在执行过程中修改model(scope中的变量),$digest()会一直被调用直到model没有再变。当调用超过10次时,$digest()会抛出一个异常”Maximum iteration limit exceeded’,以此来防止程序进入一个死循环。

$apply()
$apply([exp])

exp:string或者function(scope){}

$apply()生命周期伪代码示意图如下

function $apply(expr) {
 try {
  return $eval(expr);
 } catch (e) {
  $exceptionHandler(e);
 } finally {
  $root.$digest();
 }
}

Example
下面我们通过一个例子来说明$watch,$digest和$apply。

<script>
var module = angular.module("myapp", []);
var myController1 = module.controller("myController", function($scope) {
  $scope.data = { time : new Date() };
  $scope.updateTime = function() {
    $scope.data.time = new Date();
  }
   
  document.getElementById("updateTimeButton")
      .addEventListener('click', function() {
    console.log("update time clicked");
    $scope.data.time = new Date();
  });
});
</script>
<body ng-app="myapp">
<div ng-controller="myController">
  {{data.time}}
 
  <br/>
  <button ng-click="updateTime()">update time - ng-click</button>
  <button id="updateTimeButton" >update time</button>
</div>
</body>

这段代码会绑定$scope.data.time到HTML中显示出来,同时这个绑定会自动创建一个watch来监听$scope.date.time的变化。此外,这里还有2个按钮,第一个按钮是通过ng-click Directive来调用$scope.updateTime方法,之后AngularJS会自动执行$scope.$digest()使最新的时间显示到HTML中。第二个按钮是通过javascript代码添加一个点击事件,以此来更新HTML中的时间。但是第二个按钮是不能工作的,它的解决办法是在点击事件的最后手动的去调用$scope.$digest()方法,如下:

document.getElementById("updateTimeButton")
    .addEventListener('click', function() {
  console.log("update time clicked");
  $scope.data.time = new Date();
  $scope.$digest();
});

另外一个解决办法是调用$scope.$apply(),如下:

document.getElementById("updateTimeButton")
    .addEventListener('click', function() {
  $scope.$apply(function(){
      console.log("update time clicked");
      $scope.data.time = new Date();
    }
  );
});

以上就是本文的全部内容,希望对大家的学习有所帮助。

您可能感兴趣的文章:

  • angularJS中$apply()方法详解
  • 浅谈angular.js中实现双向绑定的方法$watch $digest $apply
  • 全面解析Angular中$Apply()及$Digest()的区别
  • AngularJS中$apply方法和$watch方法用法总结
  • AngularJS报错$apply already in progress的解决方法分析
  • Angular项目中$scope.$apply()方法的使用详解
  • angularjs 中$apply,$digest,$watch详解
  • Angular.js中$apply()和$digest()的深入理解
  • AngularJS双向数据绑定原理之$watch、$apply和$digest的应用
  • Angularjs中的$apply及优化使用详解
张贴在3