关于 Angular—OnPush策略的变更检测
当组件通过在@Component中添加 changeDetection: ChangeDetectionStrategy.OnPush,变更检测的变化:
#####不会触发的情况:
- 请求服务端数据,如xmlHttpRequest 回调中修改数据,不会触发变更检测,后续的该数据触发数据渲染也会延迟一步
- 定时事件,比如setTimeout,setInterval,promise等 不会触发变更检测
会触发的情况:
- 用户输入操作及事件,比如click, keyup,submit等,会触发变更检测!!
- input传值发生了变化(值类型的值变化或者引用类型的引用变化或者不可变类型变化),会触发该子组件的变更检测!!
无法触发变更的时候需要手动触发
-
markForCheck()
- 在组件的 metadata 中如果设置了changeDetection:ChangeDetectionStrategy.OnPush
条件,那么变化检测不会再次执行,除非手动调用该方法, 该方法的意思是在变化监测时必须检测该组件。 -
detach()
- 从变化检测树中分离变化检测器,该组件的变化检测器将不再执行变化检测,除非手动调用 reattach() 方法。 -
reattach()
- 重新添加已分离的变化检测器,使得该组件及其子组件都能执行变化检测 -
detectChanges()
- 从该组件到各个子组件执行一次变化检测
不是特殊情况,推荐使用 markForCheck
方法来触发检测,检测范围只会检测一条组件树分支上的数据。
一次事件轮询阶段 调用
markForCheck
方法都能进行检测变更
例如:
setTimeout(() => {
// this.changeRef.markForCheck(); // 位置1
this.name = "小画"
this.changeRef.markForCheck(); // 位置2
}, 2000);
// 无论放在位置1 还是位置2 都会变更检测