Angular 2更改检测如何工作? [英] How does Angular 2 change detection work?

查看:51
本文介绍了Angular 2更改检测如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In Angular 1, change detection was by dirty checking the $scope hierarchy. We would implicitly or explicitly create watchers in our templates, controllers or components.

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

In Angular 2 we no longer have $scope, but we do override setInterval, setTimeout, et al. I can see how Angular might use this to trigger a $digest, but how does Angular determine what has changed, especially given that Object.observe never made it into browsers?

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

Here is a simple example. An object defined in a service is updated in a setInterval. The DOM is recompiled each interval.

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

How is Angular able to tell that the AppComponent is watching the service, and that the value of an attribute of the service has changed?

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创建更改检测器对象(请参见

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 a change is detected, the change is propagated. E.g.,

  • 如果输入属性值更改,则新值将传播到组件的输入属性.
  • 如果{{}}绑定值更改,则新值将传播到DOM属性textContent.
  • 如果x的值在样式,属性或类绑定中发生更改,即[style.x][attr.x][class.x]–新值将传播到DOM以更新样式,HTML属性或类.
  • 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更改检测.

Angular uses Zone.js to create its own zone (NgZone), which monkey-patches all asynchronous events (browser DOM events, timeouts, AJAX/XHR). This is how change detection is able to automatically run after each asynchronous event. I.e., after each asynchronous event handler (function) finishes, Angular change detection will execute.

我在此答案中有更多详细信息和参考链接:

I have a lot more detail and reference links in this answer: What is the Angular2 equivalent to an AngularJS $watch?

这篇关于Angular 2更改检测如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆