浅析AngularJS中的$scope.$apply

本博文是基于英文文章的中文翻译和简单解释,原文请看此处

如果你使用过一段时间的angularJS,那么有极大的可能遇到过这样的代码 $scope.$apply.  表面上看来,这个代码是用来对绑定在view上的数据进行更新。那么什么时候需要用这种方式来更新绑定数据呢?为什么需要用这种方式呢?我们来一探究竟。

1.什么是javascript的多轮回(turns)机制

   稍具功能的javascript代码,都不是一次就运行完成所有功能。相反的,不同的javascript方法很多时间是在不同的轮次里完成的(其实就是通常说的回调和事件轮询). 看个例子:

<pre name="code" class="javascript">var button = document.getElementById('clickMe');
function buttonClicked(){
 alert('clicked');
}
button.addEventListener('click',buttonClicked);
function timerComplete(){
alert('hello');
}
setInterval(timerComplete,3000);

 我们分析一下这个代码有几轮(turn) 

第一轮:是这段第一次运行。 做些什么事呢?首先,找到ID为clickMe的DOM组件,为它安装监听事件。然后设置一个定时触发事件,每3秒调用一次timerComplete函数。本轮结束。

第二轮:当3秒的时候来到时,触发timerComplete函数。本轮结束。

第三轮: 当有用户点击clickMe时,触发监听事件。本轮结束。

第N轮: ...大笑

2.  多轮回(turns)和angularJS有神马关系呢

多轮回和angularJS的双向绑定有着很密切的关系。比如说,每当model数据改变时,view中相应的绑定显示也会改变,但是angularJS是怎么知道的呢?

其实很简单。angularJS会在任何一轮javascript运行结束时候,去看一下这些被绑定的数据是否发生了变化,如果绑定数据变化了,那么就去改变相应的view。

是不是很抽象? 我们举个栗子, 用angularJS写一个超简单的时钟程序:

首先是html部分

<!doctype html>
<html>
<head>
<script type="text/javascript" src="./js/angular.min.js"></script>
<script type="text/javascript" src='./js/main.js'></script>
</head>
<body ng-app='App'>
 <div ng-controller='PlayController'>
   现在时间是 {{ clock }}
 </div>
</body>
</html>

然后是我们的main.js

var app = angular.module('App',[]);
app.controller('PlayController',['$scope',function(){
 var updateClock = function(){
  $scope.clock = new Data();
};
setInterval(updateClock,1000);
}]);
运行一下,看看会发生什么?哈哈,什么也没有发生,时间一直停止。如果你打印出clock的话,你会在控制台看到每秒都有输出,但是我们的界面上就是没有改变。angularJS不是在每轮结束时都会去看看绑定数据有没有变化吗?那为什么现在会这样呢?

3. angularJS 数据绑定的前提: $scope.$apply

终于说到主题了。 原来angularJS并不是智能的去看我们的绑定数据,它需要我们用$scope.$apply来显示的告诉它。

那难道我必须在所有绑定数据的地方都调用$scope.$apply么?经验告诉我并不是这样啊。你得到它了!现实中,我们很少用到$scope.$apply。这是因为angularJS会帮我们完成这种转换。ng-click事件,$http回调等都会被自动转换。

当你需要在一个新的javascript轮回中调用一个方法,并且这个方法不是用angularJS库方法调用时,就需要使用$scope.$apply

所以,修改我们的main.js 如下:

var app = angular.module('App',[]);
app.controller('PlayController',['$scope',function(){
 var updateClock = function(){
 $scope.$apply(function(){
 $scope.clock = new Data();
});
};
setInterval(updateClock,1000);
}]);
看看效果吧,时钟动起来了。

另一种方法,就是使用angularJS自带的$interval服务。这个就留个大家了。





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值