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

AngularJS 与其他 JavaScript-MVC 框架的一个区别是,它能够使用绑定将绑定值从 JavaScript 回传到 HTML。当您为 $scope 变量赋任何值时,Angular 会“自动”执行此操作。

但这有多自动呢?有时,Angular 不会接受这个变化,所以我需要调用 $scope。$application ()或 $scope。消化()通知棱角拾取变化。有时,当我运行这两个方法中的任何一个时,它会抛出一个错误,表示摘要已经在运行中。

既然绑定({{}大括号或 ng-Attribute 中的任何内容)都与 eval 相呼应,那么这是否意味着 Angular 不断轮询 $scope 对象以查找更改,然后执行 eval 以将这些更改推送到 DOM/HTML?或者 AngularJS 以某种方式解决了使用魔法变量,当变量值改变或分配时触发事件?我从未听说过所有浏览器都完全支持它,所以我对此表示怀疑。

AngularJS 如何跟踪它的绑定和范围变量?

25708 次浏览

As you found out it's not polling, but using it's internal execution loop so that's why you need to use $apply() or $digest() to kick things into motion.

Miško's explanation is quite thorough, but the bit missing is that Angular is just trying to make $scope get back to a clear internal state whenever anything happens within its own context. This might take quite some bouncing around between model states, so that's also why you can't rely on $watch() firing only once and also why you should be careful with manually setting up relations between models or you'll end up in endless circular refreshes.

In addition to the documentation section found by Mark I think we can try to enumerate all possible sources of change.

  1. User interaction with HTML inputs ('text', 'number', 'url', 'email', 'radio', 'checkbox'). AngularJS has inputDirective. 'text', 'number', 'url' and 'email' inputs bind listener handler for 'input' or 'keydown' events. Listener handler calls scope.$apply. 'radio' and 'checkbox' bind similar handler for click event.
  2. User interaction with select element. AngularJS has selectDirective with similar behavior on 'change' event.
  3. Periodical changes using $timeout service that also do $rootScope.$apply().
  4. eventDirectives (ngClick, etc) also use scope.$apply.
  5. $http also uses $rootScope.$apply().
  6. Changes outside AngularJS world should use scope.$apply as you know.