angularJS中之$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()中之第二单参数是一个回调函数,该函数在aModel的价发生变化的当儿会受调用。当aModel发生变化的时,这个回调函数会叫调用来更新view这一点不难理解,但是,还留存一个很关键之题目!AngularJS是何等了解呀时要调用这个回调函数呢?换句话说,AngularJS是如何知晓aModel发生了变通,才调用了对应之回调函数呢?它见面周期性的周转一个函数来检查scope模型中的数额是否生了别吗?好吧,这就是$digest循环的用武之地了。

 

每当$digest循环中,watchers会被硌。当一个watcher被触发时,AngularJS会检测scope模型,如何它发出了转那么涉及到拖欠watcher的回调函数就见面被调用。那么,下一个题目便是$digest循环是当什么时候盖各种措施初步之?

 

在调用了$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包装至一个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中。

 

相关文章