Angular之变更检测

Posted by Shen Chaoran on December 13, 2017

组件会形成组件树,同样的,变化检测器(changeDetector)也会形成一颗变化检测树。 Angular 有两种变化检测机制:Default 和 OnPush。Default 模式下,每当触发变化检测时,会在整个树上检测;而 OnPush 是只有该组件的 Input 属性值发生变化时,才会触发该子树的变化检测 (内部属性发生变化不会触发,所以需要结合 cdRef.markForCheck() )。

手动触发变化检测

cdRef.markForCheck()

引用传值不会触发变化检测

如果引用的对象地址不变,值发生变化,不会触发 ngOnChanges@Input set func(v) {}。每次修改数据时都要重新new一个对象很不方便,可以使用 immutable.js。

问题

以下代码中两个子组件在一个父组件中组合,第一个子组件向父组件输出cmpSolution.cfg.keynote,而同时第二个子组件使用了第一个的输出作为输入,但是在第二个子组件的Input()属性里,没有及时更新值。 初步解决方案是:将cmpSolution.cfg.keynote深度拷贝一份,绑定到__tempKeynote,然后在子组件中使用ngOnChanges检测Input()属性是否发生变化。

<div [hidden]='currentStep !== 0'>
    <ogms-form-keynote [(ngModel)]='cmpSolution.cfg.keynote' (ngModelChange)='onKeynoteChange($event)'></ogms-form-keynote>
</div>

<div [hidden]='currentStep !== 1'>
    <ogms-form-cmp-objs [keynote]='cmpSolution.cfg.keynote' [ngModel]='cmpSolution.cfg.cmpObjs' (ngModelChange)='onCmpObjsChange($event)'></ogms-form-cmp-objs>
</div>

Reference