绑定和消化在AngularJS中如何工作?

有一件事将AngularJS与其他JavaScript-MVC框架区分开来,就是能够使用绑定将绑定值从JavaScript回显到HTML。 当你为$ scopevariables赋值的时候,Angular会“自动”执行这个操作。

但是这是多么自动? 有时,Angular不会接受更改,因此我需要调用$ scope。$ apply()或$ scope。$ digest()来通知angular度来获取更改。 有时候,当我运行这些方法中的任何一个时,它会抛出一个错误,并说摘要已经在进行中。

由于绑定({{}}括号或ng属性中的任何内容)都与eval一起回显,那么这是否意味着Angular不断轮询$ scope对象以查找更改,然后执行eval以将这些更改推送到DOM / HTML? 或者,AngularJS以某种方式计算出使用魔术variables来触发variables值更改或分配时触发的事件? 我从来没有听说过它被所有的浏览器完全支持,所以我怀疑它。

AngularJS如何跟踪绑定和范围variables?

除了Mark发现的文档部分之外,我认为我们可以尝试列举所有可能的变化来源。

  1. 用户与HTMLinput( “文本” , “数字” , “url” , “电子邮件” , “收音机” , “checkbox” )交互。 AngularJS有inputDirective 。 “文本”,“数字”,“url”和“电子邮件”input绑定“input”或“keydown”事件的侦听器处理程序 。 Listener处理程序调用scope。$ apply 。 'radio'和'checkbox'为点击事件绑定类似的处理器。
  2. 用户与select元素的交互。 AngularJS在'change'事件中有selectDirective类似的行为。
  3. 定期更改使用$超时服务 ,也做$ rootScope。$ apply() 。
  4. eventDirectives (ngClick等)也使用范围$ apply 。
  5. $ http也使用$ rootScope。$ apply() 。
  6. AngularJS世界以外的变化应该使用范围。

当你发现它不是轮询,而是使用它的内部执行循环,这就是为什么你需要使用$ apply()或$ digest()来启动事情。

Miško的解释是相当彻底的,但是缺less的一点是,Angular只是试图让$ scope在它自己的上下文中发生任何事情时回到一个明确的内部状态。 这可能需要在模型状态之间进行一些反弹,所以这也是为什么你不能仅仅依靠$ watch()触发一次,而且为什么你应该小心手动build立模型之间的关系,否则你会最终陷入无尽循环刷新。