Angular 2 变化检测是如何工作的? [英] How does Angular 2 change detection work?

查看:39
本文介绍了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 创建一个变更检测器对象(参见 ChangeDetectorRef) 每个组件,它跟踪每个模板绑定的最后一个值,例如 {{service.a}}.默认情况下,在每个异步浏览器事件(例如来自服务器的响应、单击事件或超时事件)之后,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.

我在这个答案中有更多的细节和参考链接:Angular2 相当于一个 AngularJS $watch 是什么?

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天全站免登陆