angularjs 中的$digest和$apply区别
$digest和$apply
在Angular中,有$apply和$digest两个函数,我们刚才是通过$digest来让这个数据应用到界面上。但这个时候,也可以不用$digest,而是使用$apply,效果是一样的,那么,它们的差异是什么呢?
最直接的差异是,$apply可以带参数,它可以接受一个函数,然后在应用数据之后,调用这个函数。除此之外,还有别的区别吗?
在简单的数据模型中,这两者没有本质差别,但是当有层次结构的时候,就不一样了。考虑到有两层作用域,我们可以在父作用域上调用这两个函数,也可以在子作用域上调用,这个时候就能看到差别了。
对于$digest来说,在父作用域和子作用域上调用是有差别的,但是,对于$apply来说,这两者一样。我们来构造一个特殊的示例:
var app = angular.module("test", []);
app.directive("increasea", function() {
return function (scope, element, attr) {
element.on("click", function() {
scope.a++;
scope.$digest();
});
};
});
app.directive("increaseb", function() {
return function (scope, element, attr) {
element.on("click", function() {
scope.b++;
scope.$digest(); //这个换成$apply即可
});
};
});
app.controller("OuterCtrl", ["$scope", function($scope) {
$scope.a = 1;
$scope.$watch("a", function(newVal) {
console.log("a:" + newVal);
});
$scope.$on("test", function(evt) {
$scope.a++;
});
}]);
app.controller("InnerCtrl", ["$scope", function($scope) {
$scope.b = 2;
$scope.$watch("b", function(newVal) {
console.log("b:" + newVal);
$scope.$emit("test", newVal);
});
}]);
<div ng-app="test">
<div ng-controller="OuterCtrl">
<div ng-controller="InnerCtrl">
<button increaseb>increase b</button>
<span ng-bind="b"></span>
</div>
<button increasea>increase a</button>
<span ng-bind="a"></span>
</div>
</div>
这时候,我们就能看出差别了,在increase b按钮上点击,这时候,a跟b的值其实都已经变化了,但是界面上的a没有更新,直到点击一次increase a,这时候刚才对a的累加才会一次更新上来。怎么解决这个问题呢?只需在increaseb这个指令的实现中,把$digest换成$apply即可。
当调用$digest的时候,只触发当前作用域和它的子作用域上的监控,但是当调用$apply的时候,会触发作用域树上的所有监控。
因此,从性能上讲,如果能确定自己作的这个数据变更所造成的影响范围,应当尽量调用$digest,只有当无法精确知道数据变更造成的影响范围时,才去用$apply,很暴力地遍历整个作用域树,调用其中所有的监控。
从另外一个角度,我们也可以看到,为什么调用外部框架的时候,是推荐放在$apply中,因为只有这个地方才是对所有数据变更都应用的地方,如果用$digest,有可能临时丢失数据变更。
转自: https://github.com/xufei/blog/issues/10
angularjs 中的$digest和$apply区别的更多相关文章
- 深入了解angularjs中的$digest与$apply方法,从区别聊到使用优化
壹 ❀ 引 如果有人问,在angularjs中修改模型数据为何视图会同步更新呢,我想大多数人一定会回答脏检查(Dirty Checking)相关概念.没错,在angularjs中作用域(scope) ...
- AngularJS中的digest循环$apply
欢迎大家指导与讨论 : ) 前言 Angular会拓展这个标准的浏览器流程,创建一个Angular上下文.这个Angular上下文指的是运行在Angular事件循环内的特定代码,该Angular事件循 ...
- AngularJS 中 Provider 的用法及区别
在一个分层良好的 Angular 应用中,Controller 这一层应该很薄.也就是说,应用里大部分的业务逻辑和持久化数据都应该放在 Service 里. 为此,理解 AngularJS 中的几个 ...
- angularJS中的$apply(),$digest(),$watch()
$apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$apply()和$digest()是如何工作的 ...
- AngularJS自定义Directive中link和controller的区别
在AngularJS中,自定义Directive过程中,有时用link和controller都能实现相同的功能.那么,两者有什么区别呢? 使用link函数的Directive 页面大致是: <b ...
- angularJS中$apply()方法详解
这篇文章主要介绍了angularJS中$apply()方法详解,需要的朋友可以参考下 对于一个在前端属于纯新手的我来说,Javascript都还是一知半解,要想直接上手angular JS,遇到的 ...
- angularjs中provider,factory,service的区别和用法
angularjs中provider,factory,service的区别和用法 都能提供service,但是又有差别 service 第一次被注入时实例化,只实例化一次,整个应用的生命周期中是个单例 ...
- AngularJS中的Provider们:Service和Factory等的区别
引言 看了很多文章可能还是不太说得出AngularJS中的几个创建供应商(provider)的方法(factory(),service(),provider())到底有啥区别,啥时候该用啥,之前一直傻 ...
- angularJS之$watch、$digest和$apply方法
最近项目上使用了比较多的angular JS,一直都对它感觉比较陌生,总觉得有点反直觉,这段时间,准备下定决心弄明白,这个框架到底是怎么一回事,以及它的工作原理,生命周期……一点一点的啃完它吧.首先, ...
随机推荐
- Python3 Selenium自动化测试赋值出现:WebDriverException: Message: unknown error: call function result missing 'value'
Python3 Selenium自动化测试赋值出现:WebDriverException: Message: unknown error: call function result missing ' ...
- Confluence5.8更改数据库配置
Confluence5.8更改数据库配置 第一步:是找到confluence的安装目录,我的安装目录在 /opt/atlassian/: 第二步:由于confluence把tomcat给改造了,所以c ...
- Confluence5.8协作平台软件安装(Linux)
Confluence5.8协作平台软件安装(Linux) 一.简介 Confluence是一个专业的企业知识管理与协同软件,也可以用于构建企业wiki.使用简单,但它强大的编辑和站点管理特征能够帮助团 ...
- mariadb 10.1查看per connection内存消耗
在mariadb 10.1版本中,在information_schema.processlist表中,新增了几个字段,其中有一个memory_used,其记录的是连接的内存消耗. 同时新增了一个状态变 ...
- 20145105 《Java程序设计》第6周学习总结
20145105 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 输入/输出 一.InputStream与OutputStream (一)串流设计的概念 输入串流代表对象:j ...
- linux下有线网卡出现ADDRCONF(NETDEV_UP): eth0: link is not ready的解决方法
一.背景 2018年5月24日,笔者的pc已经连续运转两天了,突然要使用有线网卡,却发现有线网卡无法正常工作,于是查看了一下内核日志: r8169 0000:05:00.0 eth0: link do ...
- luogu P2680 运输计划 65分做法
临近\(noip,AK\)不太现实,暴力才是王道,大佬无视 这里只介绍\(65\)分做法 ① \(m==1\) 的情况 很明显 就一条路径,当然要贪心选着一条路径路上的最大的边喽 傻逼分\(get 2 ...
- 【入门详解】MyBatis入门基础详解
什么是mybatis? MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的XM ...
- 【第二十八章】 springboot + zipkin(brave定制-AsyncHttpClient)
brave本身没有对AsyncHttpClient提供类似于brave-okhttp的ClientRequestInterceptor和ClientResponseInterceptor,所以需要我们 ...
- Tex: The top-level auxiliary file: *.aux I couldn't open style file IEEEtran.bst 解决方法
参考: Bibliography is not printed using Kile on Ubuntu Tex: The top-level auxiliary file: *.aux I coul ...