Angular 2 变更检测是如何工作的?

2024-05-10

在 Angular 1 中,更改检测是通过对 $scope 层次结构进行脏检查来进行的。我们会在模板、控制器或组件中隐式或显式创建观察者。

在 Angular 2 中,我们不再有 $scope,但我们确实重写了 setInterval、setTimeout 等。我可以看到 Angular 如何使用它来触发 $digest,但是 Angular 如何确定发生了什么变化,特别是考虑到 Object.observe 从未进入浏览器?

Example

这是一个简单的例子。服务中定义的对象在 setInterval 中更新。每个时间间隔都会重新编译 DOM。

Angular 如何知道 AppComponent 正在监视服务,并且服务的属性值已更改?

var InjectedService = function() {
  var val = {a:1}
  setInterval(() => val.a++, 1000);
  return val;
}

var AppComponent = ng.core
  .Component({
    selector: "app",
    template:
    `
      {{service.a}}
    `
  })
  .Class({
    constructor: function(service) {
      this.service = service;
    }
  })

AppComponent.parameters = [ new ng.core.Inject( InjectedService ) ];

document.addEventListener('DOMContentLoaded', function() {
  ng.platform.browser.bootstrap(AppComponent, [InjectedService])
});

Angular 创建一个变化检测器对象(参见变更检测器参考 https://angular.io/docs/ts/latest/api/core/index/ChangeDetectorRef-class.html) 每个组件,它跟踪每个模板绑定的最后一个值,例如{{service.a}}。默认情况下,在每个异步浏览器事件(例如来自服务器的响应、单击事件或超时事件)之后,Angular 更改检测将执行并使用这些更改检测器对象对每个绑定进行脏检查。

如果检测到更改,则会传播该更改。例如。,

  • 如果输入属性值发生更改,新值将传播到组件的输入属性。
  • If a {{}}绑定值更改,新值传播到 DOM 属性textContent.
  • 如果值x样式、属性或类绑定的更改 – 即,[style.x] or [attr.x] or [class.x]– 新值传播到 DOM 以更新样式、HTML 属性或类。

Angular 使用 Zone.js 创建自己的区域(NgZone https://angular.io/docs/ts/latest/api/core/NgZone-class.html),它对所有异步事件(浏览器 DOM 事件、超时、AJAX/XHR)进行猴子修补。这就是更改检测能够在每个异步事件之后自动运行的方式。即,在每个异步事件处理程序(函数)完成后,将执行 Angular 更改检测。

我在此答案中有更多详细信息和参考链接:Angular2 相当于 AngularJS $watch 吗? https://stackoverflow.com/questions/34569094/what-is-the-angular2-equivalent-to-an-angularjs-watch/34570122#34570122

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Angular 2 变更检测是如何工作的? 的相关文章