Angular模板中getter为何偶发触发?OnPush变更检测下多次调用原因咨询
触发多次getter调用的核心原因
- 首先明确:
ChangeDetectionStrategy.OnPush仅减少变更检测的触发时机,不会禁用变更检测运行时的模板表达式重计算逻辑。只要当前组件的变更检测被启动,所有模板绑定的表达式(包括你代码中的{{test}}getter调用)都会被执行一次,用于和旧值对比判断是否需要更新DOM。 - 你操作对应的4次变更检测触发场景分别对应:
- 第一次:修改
one变量触发。如果one是组件@Input属性、或是在事件回调/异步流订阅中赋值,属于OnPush组件默认的变更检测触发条件,会启动一轮检测 - 第二次:修改
two变量触发,逻辑和修改one一致 - 第三次:切换标签页触发window的
blur事件,Angular的Zone.js会监听这类全局DOM事件,事件触发后会启动全局变更检测,未被手动脱离检测树的OnPush组件都会被纳入检测范围 - 第四次:切换回当前标签页触发window的
focus事件,和blur事件逻辑一致,启动第四轮变更检测
- 第一次:修改
- 如果你是在同一个操作流中同时修改
one、two后切换标签,刚好会触发4轮变更检测,每轮都会执行一次testgetter,最终得到4次控制台打印。
优化方案
如果要减少不必要的getter调用,可以采用以下方案:
- 模板优先直接绑定公共变量,避免绑定getter、方法或复杂表达式
- 必须动态计算的值改用**纯管道(Pure Pipe)**实现,纯管道仅在输入参数发生变化时才会重新计算值
- 组件无频繁更新需求时,调用
ChangeDetectorRef.detach()手动脱离变更检测树,仅在需要更新视图时手动调用ChangeDetectorRef.detectChanges()触发单次检测
内容的提问来源于stack exchange,提问作者user16382159
相关产品推荐
相关产品推荐

