angularjs框架$apply,$digest和$watch理解
——我一直不太信任自己的记忆力,所以我把它们都写下来
一、$aplly()添加普通js代码到angular框架
代码演示前先看看$apply方法的作用:$apply方法可以在angularjs框架之外执行angularJs表达式。现在不明白没关系,先看代码
<p ng-controller="myCtrl">{{message}}</p> <script type="text/javascript"> function myCtrl($scope) { $scope.message ="等待3秒"; setTimeout(function () { console.log('message已刷新'); $scope.message ="等了3秒"; }, 3000); } </script>
运行上面的代码,显示“等待3秒”。但是过了3秒之后 message的内容并没有变成“等了3秒”。控制台却打印出“message已刷新”,所以 $scope.message ="等了3秒"; 这句代码已经执行了。 很显然数据的更新并没有被angular觉察到。看看另一段代码
<p ng-controller="myCtrl">{{message}}</p> <script type="text/javascript"> function myCtrl($scope) { $scope.message ="等待3秒"; setTimeout(function () { console.log('message已刷新'); $scope.$apply(function () { $scope.message ="等了3秒"; }); }, 3000); } </script>
代码可以看得出我们把刷新数据的内容加到$apply方法内部了。这次运行代码3秒过后message的值变成了 “等了3秒”。
回到开头我们再看看$apply方法的作用:$apply方法可以在angularjs框架之外执行angularJs表达式。很明显,我们更新message的值在myCtrl函数中,而不是在angular作用域下面。$apply在与其他js代码集成时很有用。
二、$digest 循环检测
在第一段代码$scope.message ="等了3秒"; 后面增加一行代码$scope.$degist()或者$scope.$apply();也能实现我们的目的。$digetst循环检测view绑定的数据是否变化,如果变化了则更新它。其实调用$apply方法接下来也是$digest检测绑定数据的变化,然后更新view。是不是一头雾水?这是angularjs初学者的第一个关隘,很多初学者对angularjs的数据绑定是如何工作的相当疑惑。一开始我也没有深究,为了便于记忆,理解成onkeydown事件的处理。
三、$watch队列
按道理来讲应该先讲$watch,然后是$digest,接着$apply。可笔者是从初学者的实用角度出发,毕竟$apply更贴近于实际应用。
在angular框架,每次绑定数据到view时都会向$watch队列里添加一个$watch
,对数据变化的检测就是$watch。看个代码
用户:<input type="text" ng-model="name"/>密码:<input type="password" ng-model="pass"/>
在这里我们有个$scope.name
,他被绑定在了第一个输入框上,还有个$scope.pass
,它被绑定在了第二个输入框上,然后我们在$watch
队列里面加入两个$watch
。
再看一段代码
app.controller('MainCtrl',function($scope){
$scope.foo ="Foo";
$scope.world ="World";});
hello{{World}}
这里虽然我们在Controller中给$scope添加了两个东西,但是view层我们只绑定了一个{{World}}
,所以只生成了一个$watch。
看一个比较复杂的例子,以便更好理解$watch
app.controller('MainCtrl',function($scope){
$scope.people =[...];//假设有10个元素});
index.html
<ul><ling-repeat="person in people">
{{person.name}} - {{person.age}}
</li></ul>
这里又生成了多少个$watch
呢?每个person有两个(一个name,一个age),然后ng-repeat又有一个,循环了十次,因此10个person一共是(2 * 10) +1
,也就是说有21个$watch
。 因此,每一个绑定到了UI上的数据都会生成一个$watch
。对,那这些$watch
是什么时候生成的呢? 当我们的模版加载完毕时,也就是在linking阶段(Angular分为compile阶段和linking阶段---译者注),Angular解释器会寻找每个directive,然后生成每个需要的$watch
。听起来不错哈,但是,然后呢?
接下来当然是$degist循环遍历$watch队列,检查是否有数据发生变化,当$degist循环完毕,如果有改变则更新view。
英语好的看看这篇文章,保证受益匪浅。
http://angular-tips.com/blog/2013/08/watch-how-the-apply-runs-a-digest/
相关推荐
在AngularJS中,$apply,$digest和$watch是核心的脏检查机制,它们共同确保了模型和视图之间的同步。下面将详细解释这三个概念及其工作原理。 1. **$apply (通知)** `$apply`是AngularJS提供的一个方法,它的主要...
- **理解$apply和$digest**:掌握何时应该手动调用$apply和$digest是使用AngularJS时的一个技巧。$apply通常在调用外部的、非AngularJS的JavaScript代码时使用,以确保数据模型的变化被AngularJS正确识别。而$digest...
AngularJS框架中的数据双向绑定是该框架的核心特性之一,它极大地简化了Web应用开发中的数据同步问题。在双向绑定机制中,视图(View)与模型(Model)之间可以自动同步,当模型变化时,视图会自动更新,反之亦然。...
2. $watch优化:尽量减少`$watch`的数量和深度,使用`$watchCollection`代替`$watch`来监听数组变化,或者使用`true`第三参数实现深比较,但要谨慎,因为这会增加计算开销。 三、过滤器的使用 过滤器在`ng-repeat`...
Scope 的 $apply 和 $digest 有时,你需要在 AngularJS 之外的地方(如 jQuery 事件处理程序或定时器)更新模型。在这种情况下,你需要调用 $scope.$apply() 方法来启动脏检查。如果脏检查已经在进行中,$apply 会抛...
AngularJS的`$destroy`方法会禁用所有的监听器、watcher以及apply/digest方法。确保在适当的时间清理watch可以帮助优化性能。 3. **考虑使用服务(Service/Factory)**:对于复杂的数据共享,考虑使用AngularJS的...
**AngularJS 开发实战:movelog 示例项目** ...综上所述,movelog项目是一个全面展示AngularJS特性和最佳实践的实例,通过深入研究其源代码,开发者能够更好地掌握AngularJS的精髓,并应用于自己的项目中。
AngularJS 是一款强大的前端JavaScript框架,用于构建动态Web应用程序。在AngularJS中,`Scope`是数据模型的主要载体,它连接了视图和控制器。深入理解Scope、其继承结构、事件系统以及生命周期对于掌握AngularJS至...