AngularJSangularJS中的$apply(),$digest(),$watch()

$apply()和$digest()在AngularJS中是五个主导概念,可是有时它们又令人疑惑。而为了领会AngularJS的办事措施,首先供给明白$apply()和$digest()是如何行事的。

$apply()和$digest()

AngularJS提供了贰个可怜酷的特征叫做双向数据绑定(Two-way Data Binding),那个特性大大简化了大家的代码编写格局。数据绑定意味着当View中有任何数据发生了变通,那么这几个变化也会自动地报告到scope的多寡上,也即意味着scope模型会自行地换代。类似地,当scope模型产生变化时,view中的数据也会更新到新型的值。那么AngularJS是怎么成功这或多或少的呢?当您写下表明式如{{
aModel }}时,AngularJS在骨子里会为您在scope模型上设置八个watcher,它用来在数码产生变化的时候更新view。那里的watcher和您会在AngularJS中装置的watcher是如出一辙的:

$scope.$watch('aModel', function(newValue, oldValue) {  

});  

盛传到$watch()中的第二个参数是3个回调函数,该函数在aModel的值产生变化的时候会被调用。当aModel产生变化的时候,那几个回调函数会被调用来更新view那一点简单明白,不过,还设有一个很要紧的题材!AngularJS是何等知道怎么样时候要调用那一个回调函数呢?换句话说,AngularJS是何许知晓aModel爆发了变动,才调用了相应的回调函数呢?它会周期性的周转二个函数来检查scope模型中的数据是还是不是发生了扭转吧?好呢,那正是$digest循环的用武之地了。

 

在$digest循环中,watchers会被触发。当一个watcher被触发时,AngularJS会检查和测试scope模型,怎么着它爆发了变化那么涉及到该watcher的回调函数就会被调用。那么,下1个题材正是$digest循环是在怎么着时候以种种艺术起首的?

AngularJS, 

在调用了$scope.$digest()后,$digest循环就起来了。假使你在多个ng-click指令对应的handler函数中改变了scope中的一条数据,此时AngularJS会自动地经过调用$digest()来触发一轮$digest循环。当$digest循环初始后,它会触发种种watcher。那一个watchers会检查scope中的当前model值是不是和上叁遍总结获得的model值分歧。假如不相同,那么相应的回调函数会被实践。调用该函数的结果,正是view中的表明式内容(译注:诸如{{ aModel
}})会被更新。除了ng-click指令,还有一部分任何的built-in指令以及服务来让你改变models(比如ng-model,$timeout等)和机动触发叁遍$digest循环。

 

方今停止勉强能够!可是,有三个不奇怪。在上边包车型地铁事例中,AngularJS并不直接调用$digest(),而是调用$scope.$apply(),后者会调用$rootScope.$digest()。由此,一轮$digest循环在$rootScope起先,随后会访问到全数的children scope中的watchers。

 

目前,假如你将ng-click指令关联到了一个button上,并传播了三个function名到ng-click上。当该button被点击时,AngularJS会将此function包装到2个wrapping function中,然后传入到$scope.$apply()。因而,你的function会不奇怪被实践,修改models(假若须求的话),此时一轮$digest循环也会被触发,用来保障view也会被更新。

 

Note: $scope.$apply()会自行地调用$rootScope.$digest()。$apply()方法有二种格局。第二种会接受二个function作为参数,执行该function并且触发一轮$digest循环。第二种会不收受任何参数,只是触发一轮$digest循环。大家立即会晤到为何第叁种情势更好。

 

如几时候手动调用$apply()方法?

假定AngularJS总是将我们的代码wrap到叁个function中并传播$apply(),以此来初阶一轮$digest循环,那么什么样时候才需求大家手动地调用$apply()方法吧?实际上,AngularJS对此有所尤其明显的供给,正是它只担负对发生于AngularJS上下文环境中的变更会做出自动地响应(即,在$apply()方法中发生的对于models的转移)。AngularJS的built-in指令正是这么做的,所以任何的model变更都会被反映到view中。但是,倘诺您在AngularJS上下文之外的其余地方修改了model,那么您就要求经过手动调用$apply()来布告AngularJS。那就像是告诉AngularJS,你改改了有个别models,希望AngularJS帮您触发watchers来做出科学的响应。

 

例如,借使您利用了JavaScript中的setTimeout()来更新三个scope model,那么AngularJS就从不章程知道您转移了什么样。那种景观下,调用$apply()正是你的职责了,通过调用它来触发一轮$digest循环。类似地,要是你有二个命令用来安装二个DOM事件listener并且在该listener中期维修改了有的models,那么你也急需通过手动调用$apply()来保险变更会被科学的反映到view中。

 

相关文章