为什么如下Angular示例代码运行后渲染输出3而非预期的1?
问题原因解析
核心根因:Angular 变更检测机制 + 模板绑定表达式存在副作用
输出不符合预期是两个因素共同作用的结果:
- 模板绑定的
countgetter 内部存在修改状态的副作用,不符合 Angular 对模板表达式的要求 - Angular 开发模式下的多轮变更检测逻辑会多次调用绑定的 getter
具体细节说明
模板表达式的调用规则
Angular 无法预判 getter 类的绑定表达式返回值是否发生变化,所以每次触发变更检测时,都会重新执行一遍绑定的表达式,获取最新值来判断是否需要更新视图。你在countgetter 中写了this.i++,每次调用都会修改全局的i变量,相当于每次变更检测都会给i累加1。开发模式的多轮变更检测
为了避免状态变更和视图更新不一致的问题,Angular 在开发模式下默认会执行两轮变更检测:
- 第一轮是正常的业务变更检测,用来更新视图内容
- 第二轮是校验性质的变更检测,用来确认第一轮变更检测结束后没有新的状态修改,如果两轮结果不一致会抛出 「表达式在检查后发生了变更」 的常见报错
加上组件初始化阶段的首次取值调用,countgetter 总共被调用了3次,i从0累加到3,最终渲染结果就是3。
修复建议
模板绑定的表达式应该遵循 幂等、无副作用 的原则,多次调用返回的结果应该一致,也不应该修改其他组件状态:
- 如果需要返回固定的初始值,直接在 getter 中返回常量,或者把状态修改的逻辑放到
ngOnInit等生命周期钩子中执行,不要放在绑定表达式里 - 如果是需要累加的计数逻辑,不要通过 getter 绑定到模板,单独写触发逻辑来更新计数变量,再直接绑定变量到模板即可
内容的提问来源于stack exchange,提问作者Display Name
相关产品推荐
相关产品推荐

