AngularJs学习笔记(3)--$scope中的$apply和$digest方法
2017-04-22 22:36
393 查看
http://xlows.blog.51cto.com/5380484/1425325
首先,我们利用angular在页面上输出当前的时间,这个并不难,代码如下:
此时页面会输出当前时间。
那么,现在有一个需求,要求时间每秒中更新一次。
我们把js代码改成如下:
在运行,发现页面并没有每秒刷新一次。那么在Model中变的时候,如何通知页面变化呢?
(1)什么是scope
scope是一个指向应用model的object,也是表达式的执行上下文,它被放置于一个类似应用的DOM结构的层次结构中。
(2)angular是怎么知道变量发生了改变
①要知道一个变量变了,方法不外乎两种
能通过固定的接口才能改变变量的值,比如说只能通过set()设置变量的值,set被调用时比较一下就知道了。这种方法的缺点是写法繁琐。
脏检查,将原对象复制一份快照,在某个时间,比较现在对象与快照的值,如果不一样就表明发生变化,这个策略要保留两份变量,而且要遍历对象,比较每个属性,这样会有一定性能问题。
②angular的策略
angular的实现是使用脏检查
不会脏检查所有的对象,当对象被绑定到html中,这个对象添加为检查对象(watcher)。
不会脏检查所有的属性,同样当属性被绑定后,这个属性会被列为检查的属性。
在angular程序初始化时,会将绑定的对象的属性添加为监听对象(watcher),也就是说一个对象绑定了N个属性,就会添加N个watcher。
③什么时候去脏检查
angular所有系统的方法中都会触发比较事件,比如:
controller初始化的时候,所有以ng-开头的时间执行后,都会触发脏检查。
因此,可以想到,在第一次加载页面时候,controller初始化的时候,会检查其中的date,进行第一次赋值。
而后setInterval每秒触发一次,此时date虽然变了,但是并没有触发脏检查,因此不会触发页面上的改变。
(3)手动触发脏检查
$apply仅仅只是进入angular context,然后通过$digest方法去触发脏检查
$apply如果不给参数的话,会检查该$scope里的所有监听的属性,推荐给上参数。
通过上面的说明,我们可以js代码改成如下:
此时,页面每个1秒会更新一次时间。
看一下$apply的代码:
可以看到,$apply方法首先会通过$eval来解析里面的表达式,如果表达式有错会抛出错误,如果没有错误才会触发$digest方法。
(4)关于$digest()
其控制器所属的scope和其所有子scope的脏检查,脏检查又会触发$watch(),整个angular双向绑定机制就活了过来
这里不建议直接调用$digest(),而应该使用$apply,$apply其实不能把信直接送给$digest,之间还有$eval门卫把关,如果$apply带的表达式不合法,$eval会把错误交给$exceptionHandler,合法才会触发$digest,所有更安全。
首先,我们利用angular在页面上输出当前的时间,这个并不难,代码如下:
那么,现在有一个需求,要求时间每秒中更新一次。
我们把js代码改成如下:
(1)什么是scope
scope是一个指向应用model的object,也是表达式的执行上下文,它被放置于一个类似应用的DOM结构的层次结构中。
(2)angular是怎么知道变量发生了改变
①要知道一个变量变了,方法不外乎两种
能通过固定的接口才能改变变量的值,比如说只能通过set()设置变量的值,set被调用时比较一下就知道了。这种方法的缺点是写法繁琐。
脏检查,将原对象复制一份快照,在某个时间,比较现在对象与快照的值,如果不一样就表明发生变化,这个策略要保留两份变量,而且要遍历对象,比较每个属性,这样会有一定性能问题。
②angular的策略
angular的实现是使用脏检查
不会脏检查所有的对象,当对象被绑定到html中,这个对象添加为检查对象(watcher)。
不会脏检查所有的属性,同样当属性被绑定后,这个属性会被列为检查的属性。
在angular程序初始化时,会将绑定的对象的属性添加为监听对象(watcher),也就是说一个对象绑定了N个属性,就会添加N个watcher。
③什么时候去脏检查
angular所有系统的方法中都会触发比较事件,比如:
controller初始化的时候,所有以ng-开头的时间执行后,都会触发脏检查。
因此,可以想到,在第一次加载页面时候,controller初始化的时候,会检查其中的date,进行第一次赋值。
而后setInterval每秒触发一次,此时date虽然变了,但是并没有触发脏检查,因此不会触发页面上的改变。
(3)手动触发脏检查
$apply仅仅只是进入angular context,然后通过$digest方法去触发脏检查
$apply如果不给参数的话,会检查该$scope里的所有监听的属性,推荐给上参数。
通过上面的说明,我们可以js代码改成如下:
看一下$apply的代码:
(4)关于$digest()
其控制器所属的scope和其所有子scope的脏检查,脏检查又会触发$watch(),整个angular双向绑定机制就活了过来
这里不建议直接调用$digest(),而应该使用$apply,$apply其实不能把信直接送给$digest,之间还有$eval门卫把关,如果$apply带的表达式不合法,$eval会把错误交给$exceptionHandler,合法才会触发$digest,所有更安全。
相关文章推荐
- AngularJs学习笔记(3)--$scope中的$apply和$digest方法
- AngularJs学习笔记(4)--$scope里的$watch方法
- AngularJs学习笔记(4)--$scope里的$watch方法
- angularjs学习笔记3-directive中scope的绑定修饰符
- AngularJs学习笔记--Scope
- angularjs学习笔记--ng-class的三种使用方法
- angularjs学习笔记—工具方法
- AngularJS基础——$scope里的$apply方法和$watch方法
- AngularJs学习笔记--Scope
- angularjs学习笔记—工具方法
- Angularjs学习笔记5_scope和$rootScope
- angularjs学习笔记—工具方法
- AngularJS学习笔记之directive——scope选项与绑定策略
- 【AngularJS】4.AngularJS $scope里面的$apply方法和$watch方法
- AngularJs学习笔记(3)——scope
- AngularJS学习笔记之directive——scope选项与绑定策略
- AngularJS学习笔记之directive——scope选项与绑定策略
- angularjs学习笔记—工具方法
- AngularJs学习笔记--Scope
- AngularJS学习笔记--服务的创建方法factory() service() provider()等