Autumn_Ning_Blog
Autumn_Ning_Blog copied to clipboard
Angular的双向数据绑定
trafficstars
Scope是一个简单的JavaScript对象,我们可以像其他对象一样添加属性
监控对象属性:$watch和$digest
$watch $digest 相辅相成,两者在一起,构成了Angular作用域的核心:数据变化的响应
使用$watch,可以在scope上添加一个监听器,当scope上发生了变更时,监听器会收到提示,给$watch指定两个函数,就可以创建一个监听器:
- 一个监控函数,用于指定所关注的那部分数据
- 一个监听函数,用于在数据变更的时候接受提示
另一方面就是$digest函数 它执行了所有在作用域上注册过的监听器,遍历所有监听器,调用它们的监听函数
这些本身没什么大用,我们要的是能检测由监控函数指定的值是否确实变更了,然后调用监听函数
脏值检测
$digest函数的作用是调用这个监控函数,并且比较它返回的值和上一次返回的值的差异,如果不相同,监听器就是脏的,它的监听函数就应当被调用
当数据脏的时候持续Digest时,需要让它持续的遍历所有监听器,知道监控的值停止变更 可以使用一个外层循环来运行,而Angular的实现是通过内循环执行的,因为可能会两个监听器互相监控了对方的变更,那么就会状态始终不稳定,那么这个时候我们可以设置一个TTL,超过了TTL则停止迭代
$eval 在作用的上下文上执行代码,它使用一个函数作参数,所做的事情就是立即执行这个传入的函数,并把作用域自身当作参数传递给它,返回的是这个函数的返回值
Scope.prototype.$eval = function(expr, locals) {
return expr(this, locals);
}
$apply集成外部代码与digest循环
$apply使用函数作参数,它用$eval执行这个函数,然后通过$digest触发digest循环
Scope.prototype.$apply = function(expr) {
try {
return this.$eval(expr);
} finally {
this.$digest();
}
};