原文地址:https://www.cnblogs.com/cme-kai/p/8497146.html
参考:https://blog.csdn.net/hlwz5735/article/details/91451784
在OnPush策略下,Angular不会运行变化检测(Change Detection ),除非组件的input接收到了新值。接收到新值的意思是,input的值或者引用发生了变化。这样听起来不好理解,看例子:
子组件接收一个balls(别想歪:))输入,然后在模板遍历这个balls数组并展示出来。初始化2秒后,往balls数组push一个new ball:
注意:因为鼠标键盘事件会触发变化检测,所以这里使用定时器!
现在是不使用OnPush策略的情况。2秒后,new ball就被添加到视图中了。
当使用OnPush变化检测策略的时候,new ball并不会被添加到视图中:
但是,如果在父组件改变input的值,视图是会更新的,因为这样Angular会运行变化检测:
这样就相当于改变了balls的引用。
但是,如果不改变balls的引用,只给它push一个值,视图是不会更新的:
这时如果有需要,我们可以用ChangeDetectorRef.detectChanges()手动触发变化检测。
开启/关闭修改检测,并手动触发
有时候我们希望关闭修改检测,比如这样的场景:大量数据通过websocket服务端蜂拥而至,而我们则希望只要每5秒钟触发一次具体UI局部更新就好。为了实现这种效果,我们先给组件注入修改检测器:
如你所见,我们分离了修改检测器,这会导致修改检测功能的关闭。之后我们通过每5秒钟调用一次detectChanges()方法来手动触发它。
总结
Angular默认的修改检测机制同Angular 1很类似:它会在浏览器事件之前和之后比较模板表达式中的值从而确定是否存在修改。所有的组件都会执行。但是也有一些重要的不同点:
第一点是不存在修改检测循环(在Angular 1中称为消化循环)。这使得仅通过查看模板和控制器就可以推断出每个组件。
另一点不同之处,因为修改检测器的构建方式不同,组件的修改检测机制比之前快得多。
最后,和Angular 1不同, 修改检测机制是可以自定义的。
对于95%的应用场景,可以信誓旦旦地说,Angular的修改检测都能良好的工作,并且关于它我们并不需要了解得太多。但是弄明白修改检测是如何工作的依然有用,有如下原因:
首先它可以帮助我们弄明白一些在开发时可能会遇到的异常信息,如修改检测循环;
有助于我们阅读异常堆栈追踪,那些突然蹦出来的zone.afterTurnDone()看起来终于不那么头痛了;
在性能短缺(不过你真的确定不在那些巨型数据表格上使用分页机制吗?)的场景下,理解修改检测可以帮助我们进行性能优化。