Angular 2更改检测如何工作?
收藏

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

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

这是一个简单的例子。服务中定义的对象在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 creates a change detector object (see ChangeDetectorRef) per component, which tracks the last value of each template binding, such as {{service.a}}. By default, after every asynchronous browser event (such as a response from a server, or a click event, or a timeout event), Angular change detection executes and dirty checks every binding using those change detector objects.

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

  • If an input property value changed, the new value is propagated to the component's input property.
  • If a {{}} binding value changed, the new value is propagated to DOM property textContent.
  • If the value of x changes in a style, attribute, or class binding – i.e., [style.x] or [attr.x] or [class.x] – the new value is propagated to the DOM to update the style, HTML attribute, or class.

Angular使用Zone.js创建自己的区域(NgZone),该区域可猴子修补所有异步事件(浏览器DOM事件,超时,AJAX / XHR)。这样,更改检测能够在每个异步事件之后自动运行。即,在每个异步事件处理程序(函数)完成后,将执行Angular更改检测。

我在此答案中有更多详细信息和参考链接:Angular2等效于AngularJS $ watch?

    公众号
    关注公众号订阅更多技术干货!