博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
angularjs 中的$digest和$apply区别
阅读量:6238 次
发布时间:2019-06-22

本文共 1813 字,大约阅读时间需要 6 分钟。

$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);    });}]);

 

这时候,我们就能看出差别了,在increase b按钮上点击,这时候,a跟b的值其实都已经变化了,但是界面上的a没有更新,直到点击一次increase a,这时候刚才对a的累加才会一次更新上来。怎么解决这个问题呢?只需在increaseb这个指令的实现中,把$digest换成$apply即可。

当调用$digest的时候,只触发当前作用域和它的子作用域上的监控,但是当调用$apply的时候,会触发作用域树上的所有监控。

因此,从性能上讲,如果能确定自己作的这个数据变更所造成的影响范围,应当尽量调用$digest,只有当无法精确知道数据变更造成的影响范围时,才去用$apply,很暴力地遍历整个作用域树,调用其中所有的监控。

从另外一个角度,我们也可以看到,为什么调用外部框架的时候,是推荐放在$apply中,因为只有这个地方才是对所有数据变更都应用的地方,如果用$digest,有可能临时丢失数据变更。

 

转自: https://github.com/xufei/blog/issues/10

转载地址:http://agbia.baihongyu.com/

你可能感兴趣的文章
成长7 - lambda,filter,map的运用
查看>>
New Concept English Two 18 46
查看>>
Qt 删除目录
查看>>
Git 移除某些文件
查看>>
poj2940
查看>>
django做form表单的数据验证
查看>>
【OpenFOAM】——OpenFOAM入门算例学习
查看>>
STL UVA 11991 Easy Problem from Rujia Liu?
查看>>
模拟 URAL 1149 Sinus Dances
查看>>
Oracle 11G 数据库迁移【expdp/impdp】
查看>>
17.EXTJs 中icon 与iconCls的区别及用法!
查看>>
3.mybatis实战教程(mybatis in action)之三:实现数据的增删改查
查看>>
Caused by: Unable to load bean: type: class:com.opensymphony.xwork2.ObjectFactory - bean - jar
查看>>
让你拥有超能力:程序员应该掌握的统计学公式
查看>>
互联网组织的未来:剖析 GitHub 员工的任性之源
查看>>
Java 开源博客 Solo 1.4.0 发布 - 简化
查看>>
Oracle巡检
查看>>
【转载】胜者树
查看>>
查看mysql数据库存放的路径|Linux下查看MySQL的安装路径
查看>>
selenium+testNG+Ant
查看>>