前言
相信大家在一开始用angular
做项目的时候,一定碰到过$scope.$apply()
方法,表面上看,这像是一个帮助你进行数据更新的方法,那么,它为何存在,我们又该如何使用它呢?
JavaScript执行顺序
JavaScript
单线程操作,代码按照代码片段的顺序来之行,每个代码块从运行到结束都不会被打断,这也是为什么会发生浏览器阻塞的情况,往往是有一部分在运行,而导致其他所有的代码段冻结。
每当有耗费时间较多的任务出现,例如等待一个click
事件,等待Ajax
请求的回应,我们都会设定一个回调函数,当click
事件被触发或者计时器完成,就会创建一个新的JavaScript turn
,并执行完回调函数。如果还不清楚js
的运行机制,可以前往js运行机制这篇文章,可能会有更多的帮助。
var button = document.getElementById('clickMe');
function buttonClicked () {
alert('the button was clicked');
}
button.addEventListener('click', buttonClicked);
function timerComplete () {
alert('timer complete');
}
setTimeout(timerComplete, 2000);
当JavaScript
代码开始运行,先找到一个botton
,并添加一个点击的监听事件,且设定一个timeout
。浏览器会在这段代码执行完毕之后进行web
的更新,并且接受用户的输入。
如果浏览器检测到一个新的点击事件发生,他就会开始一个turn
,来执行buttonClicked
函数。当函数执行结束,这个阶段也随之结束。
经过2000
毫秒,浏览器会创建一个过程来执行timerComplete
。在这两个过程之间,页面被重绘,输入被接收。
如何来更新绑定数据
Angular
为我们提供了一些接口来绑定JavaScript
代码与数据。
进行数据变化检查的实际上是$digest
函数,但是通常我们不是直接使用$digest
函数,而是使用$apply
,$apply
函数接收表达式或者函数作为参数后调用$digest
来更新监控器。
那我们究竟要什么时候来调用$apply
呢,实际上,Angular
几乎在所有提供的代码中添加了$apply
,如ng-click
,初始controller
,$http
的回调操作,在这,你并不需要亲自调用 $apply
,而且重复的调用会引起错误。
因此,当你运行了【一个新阶段】,并且这部分并不属于Angular
库的情况下才需要使用$apply
。这有一段关于setTimeout
的代码,在经过了2000
毫秒的延迟之后,代码进入执行了【一个新的阶段】,但是Angular
并不知道数据有更新,因此更新并不会被显示。
$scope.message = "等2秒后进行更新";
setTimeout(function () {
$scope.message = "时间到";
// AngularJS unaware of update to $scope
}, 2000);
这时候,大家会发现2秒钟后,数据是没有变化的,因为此时Angular
没有检测到数据的更新,所以,此时我们需要使用$scope.$apply()
这个函数了,代码更改后如下:
$scope.message = "等2秒后进行更新";
setTimeout(function () {
$scope.$apply(function() {
$scope.message = "时间到";
})
}, 2000);
为了方便大家的使用,Angular
提供了$timeout
来代替setTimeout
,相当于在其中默认调用$apply
。
如果在你的代码中使用了除$http
之外的Ajax
调用,除了ng-*
之外的监听器,或者除了$timeout
之外的计时器,都应该使用$scope.$apply
来同步显示绑定。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!