Angular 组件的生命周期(Component Lifecycle Hook)

摘要

当 Angular 实例化组件类并渲染组件视图及其子视图时,组件实例的生命周期就开始了。生命周期一直伴随着变更检测,Angular 会检查数据绑定属性何时发生变化,并按需更新视图和组件实例。当 Angular 销毁组件实例并从 DOM 中移除它渲染的模板时,生命周期就结束了。当 Angular 在执行过程中创建、更新和销毁实例时,指令就有了类似的生命周期。

你的应用可以使用生命周期钩子方法来触发组件或指令生命周期中的关键事件,以初始化新实例,需要时启动变更检测,在变更检测过程中响应更新,并在删除实例之前进行清理。

生命周期及顺序

  1. ngOnChanges(): 当 Angular 设置或重新设置数据绑定的输入属性时响应。
  2. ngOnInit(): 在 Angular 第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。
  3. ngDoCheck(): 每次执行变更检测时的 ngOnChanges() 和 首次执行变更检测时的 ngOnInit() 后调用。
  4. ngAfterContentInit(): 当 Angular 把外部内容投影进组件视图或指令所在的视图之后调用。
  5. ngAfterContentChecked(): ngAfterContentInit() 和每次 ngDoCheck() 之后调用
  6. ngAfterViewInit(): 当 Angular 初始化完组件视图及其子视图或包含该指令的视图之后调用。
  7. ngAfterViewChecked(): ngAfterViewInit() 和每次 ngAfterContentChecked() 之后调用。
  8. ngOnDestroy(): 每当 Angular 每次销毁指令/组件之前调用,清理释放资源。

响应生命周期事件

我们以通过实现一个或多个 Angular中定义的生命周期钩子接口来响应组件或指令生命周期中的事件。每个接口都有唯一的一个钩子方法,它们的名字是由接口名再加上 ng 前缀构成的。例如:

1
2
3
4
5
6
7
8
9
@Component()
export class DemoComponent implements OnInit {
constructor() { }

// implement OnInit's `ngOnInit` method
ngOnInit() {
// do something here
}
}

说明:
1) 通过生命周期钩子接口来响应生命周期中的事件,需要在类名之后,声明实现(implements) 具体的钩子接口。然后代码中定义个钩子函数才能被执行。如 ngOnInit() 对应 接口OnInit
2) 可以实现多个钩子接口,例如 export class DemoComponent implements OnInit, OnDestroy {

主要生命周期事件

初始化事件 ngOnInit()

使用 ngOnInit() 方法执行以下初始化任务:

  1. 逻辑稍复杂,不适合放到构造函数中的逻辑
  2. 初始化中的数据访问逻辑
  3. 处理需要根据父组件传入参数(@Input)进行初始化的逻辑

实例销毁 ngOnDestroy()

把清理逻辑放进 ngOnDestroy() 中,这个逻辑就必然会在 Angular 销毁该指令之前运行。下列逻辑可言放到ngOnDestroy():

  • 取消订阅可观察对象和 DOM 事件。
  • 停止 interval 计时器。
  • 反注册该指令在全局或应用服务中注册过的所有回调。
  • 释放其他占有的资源。

总结

  1. 使用生命周期事件钩子函数,别忘了类名后面implements 相应的接口,否则不生效;
  2. 初始化代码,区分哪些放构造函数,哪些放 ngOnInit();
  3. 可以精简的钩子事件方法来避免性能问题;
  4. ngOnChanges()发生的非常频繁,加入复杂逻辑会影响性能;