Autumn_Ning_Blog icon indicating copy to clipboard operation
Autumn_Ning_Blog copied to clipboard

Angular的双向数据绑定

Open wangning0 opened this issue 8 years ago • 0 comments
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();
  }
};

wangning0 avatar Jun 02 '17 01:06 wangning0