Angular变化检测Angular变化检测机制比AngularJs中的等效机制更透明,更容易推理。但在某些情况下(比如做性能优化的时候),我们确实需要知道幕后发生了什么。因此,让我们通过以下主题更深入地探讨变更检测:如何实施变更检测?Angular变化检测器是什么样子的,我能看到它吗?默认的变更检测机制是如何工作的打开/关闭变更检测并手动触发它以避免变更检测循环:生产模式vs开发模式什么是OnPush变更检测模式?使用Immutable.js简化Angular应用程序的构建如何实施变更检测?Angular可以检测组件数据何时发生更改,并自动重新呈现视图以反映该更改。但是它如何在页面上任何地方都可能发生的低级别事件(例如按钮单击)之后执行此操作?要理解这是如何工作的,我们需要首先认识到Javascript中的整个运行时是设计为可重新加载的。如果需要,我们可以覆盖原生函数,如String或Number。覆盖浏览器默认机制当Angular应用程序启动时,它会修补几个低级浏览器API,例如addEventListener,这是一个用于注册所有浏览器事件的浏览器函数,包括点击处理程序。Angular将其替换为另一个新版本的addEventListener://这是新版本的addEventListenerfunctionaddEventListener(eventName,callback){//调用真正的addEventListenercallRealAddEventListener(eventName,function(){//首先调用原始回调callback(...);//然后运行特定于Angular的功能varchanged=angular.runChangeDetection();if(changed){angular.reRenderUIPart();}});新版本的addEventListener添加了更多功能:不仅调用已注册的回调,而且Angular有机会运行更改检测并更新UI。这个低级运行时补丁操作是如何工作的?浏览器API的这种低级修补是由Angular附带的名为Zone.js的库完成的。了解什么是区域很重要。区域只不过是在JavascriptVM的多轮执行中存活下来的执行上下文。这是我们可以用来向浏览器添加额外功能的通用机制。Angular在内部使用Zones来触发变化检测,但另一种可能的用途是应用程序分析,或跟踪跨多个VM轮次运行的长堆栈跟踪。浏览器支持异步API修补以下常见浏览器机制以支持更改检测:所有浏览器事件(单击、鼠标悬停、按键等)setTimeout()和setInterval()AjaxHTTP请求事实上,Zone.js修补许多其他浏览器API以透明地触发Angular变化检测,例如Websockets。这种机制的一个限制是,如果出于某种原因Zone.js不支持异步浏览器API,则不会触发更改检测。这解释了变化检测是如何被触发的,但是它一旦被触发又是如何工作的呢?变更检测树每个Angular组件都有一个关联的变更检测器,它是在应用程序启动时创建的。这是一个例子:@Component({selector:'todo-item',template:`{{todo.owner.firstname}}-{{todo.description}}-已完成:{{todo.completed}}`})exportclassTodoItem{@Input()todo:Todo;@Output()toggle=newEventEmitter