• 变化检测
    1、一些异步事件发生后导致绑定值发生改变时就会进行变化检测,如用户输入,xhr,定时事件等。这些异步事件被 zone.js 进行了包装,而 Angular 就是通过引入 zone.js 从而获得了异步事件发生时的通知,进而开始执行脏值检测。(AngularJS 是手动通过代码来触发 脏值检测$scope.digest())
    2、Angular 是单向数据流,而 AngularJS 则是双向数据流。这就导致了 AngularJS 为了确保数据模型的稳定需要进行多次脏值检测;而 Angular 只需进行一次脏值检测就能确保数据模型稳定,如果一次脏值检测完成时数据模型未能稳定,Angular会抛出异常,说明用户代码未遵循单向数据流原则,这是不被允许的。
    3、检测策略:default 和 onPush 两种策略。default 策略,只要view里用到的变量值发生变化就会检测,onPush 策略则是只有 @input 属性的引用发生变化才进行检测。多数情况下使用 onPush 策略 + 注入 ChangeDectector 手动调用 cdr.detectChanges() 方法触发检测
  • 依赖注入
    四种依赖注入法:useValue,useClass,useExsiting,useFactory

原理

  • 每个组件对应一个视图
  • 每个视图都有一个状态:FirstCheck,ChecksEnabled,Error,Destroyed
  • 视图的状态决定 Angular 的 Change Detection 是否起作用
  • 当组件状态是 ChecksEnabled=false,Error,Destroyed 时,Change Detection 将跳过该组件
  • 所有组件默认状态都是 ChecksEnabled = true,除非设置了 ChangeDetectionStrategy.OnPush
  • 组件状态可以组合,不是四选一,比如可以是 FirstCheck,ChecksEnabled 的组合
  • 每个视图还对应一个 viewRef , 每当异步事件触发,最顶层的 viewRef 触发 Change Detection,然后触发其子视图的 Change Detection
  • 当一个视图触发 Change Detection 时,会发生这些事
    1、更新子组件的 input
    2、更新子组件状态(是否可Change Detection)
    3、如果子组件 input 变化了,就调用子组件 ngOnChanges
    4、调用子组件 OnInit and ngDoCheck
    5、调用子组件 AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked
    6、调用OnDestroy,如果父/子组件 OnDestroy
    7、更新当前视图的DOM
    8、对子组件运行 Change Detection
    9、设置当前组件状态 ChecksEnabled = true/false
    10、设置当前组件状态 FirstCheck = false
  • 注意,即使子组件状态ChecksEnabled=false,子组件的 ngOnChanges 在 input 变化时也可触发

参考