Angular - 组件生命周期
Angular 组件在其生命周期中会经历一系列阶段/事件。在继续学习 Angular 的旅程之前,理解组件在其整个生命周期中如何与框架和 DOM 交互是非常必要的。
当 Angular 组件被构造时,它首先进入变更检测阶段,检查输入是否有变化并相应行事。然后,初始化阶段启动,继续进入其他阶段,最终在销毁阶段被销毁。
Angular 中的组件生命周期阶段
Angular 组件生命周期的不同阶段如下所示 −
创建: 这是第一个阶段,组件在此阶段被实例化。
变更检测: 然后,Angular 尝试检测应用视图和内容的变更。
渲染: 变更检测之后,新的模板会被更新。
销毁: 最后,组件被销毁。
Angular 中的组件生命周期钩子
Angular 组件的每个阶段都关联一个生命周期钩子接口,可以实现该接口在特定阶段执行任意操作。通常,生命周期钩子指的是生命周期钩子接口的方法。让我们来看看这些阶段、它们的顺序以及对应的钩子。
| 阶段 | 生命周期钩子 | 描述 |
|---|---|---|
创建 |
Constructor |
当 Angular 首次实例化组件时,Constructor 会运行。 |
变更检测 |
ngOnChanges() |
变更检测是第一个阶段,Angular 组件会检查输入的变更并相应行事。它对应的生命周期钩子是 ngOnChanges()。此钩子在首次初始化过程中于 ngOnInit() 之前运行。 |
ngOnInit() |
ngOnInit() 生命周期钩子在 ngOnChanges() 之后且仅运行一次。它用于基于初始输入执行必要的初始化过程。 |
|
ngDoCheck() |
接下来,Angular 尝试检测组件的变更并相应行事。用于检查的生命周期钩子是 ngDoCheck()。即使输入绑定的属性没有变化,此钩子也会被调用。避免定义此钩子,因为它可能会影响页面的性能。 |
|
ngAfterContentInit() |
此生命周期钩子在组件内容中所有嵌套子元素初始化之后仅调用一次。 |
|
ngAfterContentchecked() |
它在每次变更检测阶段中,组件内容内的嵌套子元素被检查变更之后被调用。 |
|
ngAfterViewInit() |
接下来是视图初始化阶段,Angular 设置组件模板的各种子视图。用于视图初始化阶段的生命周期钩子是 ngAfterViewInit()。 |
|
ngAfterViewchecked() |
现在,Angular 尝试检测组件/指令视图的变更。用于视图检查阶段的生命周期钩子是 ngAfterViewchecked()。 |
|
渲染 |
afterNextRender() |
当所有组件渲染到 DOM 时仅运行一次。 |
afterRender() |
每次所有组件渲染到 DOM 后运行。 |
|
销毁 |
ngOnDestroy() |
在最终阶段,ngOnDestroy() 钩子被调用以销毁组件/指令。 |
组件生命周期钩子的执行顺序
让我们通过钩子来查看任意组件/指令的生命周期序列。
- ngOnChanges
- ngOnInit
- ngDoCheck
- ngAfterContentInit
- ngAfterContentChecked
- ngAfterViewInit
- ngAfterViewChecked
- ngOnChanges
- ngDocheck
- ngAfterContentChecked
- ngAfterViewchecked
- 重复步骤 8 - 11 直到销毁
- ngOnDestroy
示例
让我们创建一个新组件 MyLifecycleComponent,连接所有钩子,并使用控制台输出检查生命周期的序列。
步骤 1: 使用以下命令通过 Angular CLI 创建一个新组件 −
ng generate component my-lifecycle-sample
这将创建新组件及其相关的模板和样式,如下所示。
ng generate component my-lifecycle-sample CREATE src/app/my-lifecycle-sample/my-lifecycle-sample.spec.ts (633 bytes) CREATE src/app/my-lifecycle-sample/my-lifecycle-sample.ts (247 bytes) CREATE src/app/my-lifecycle-sample/my-lifecycle-sample.css (0 bytes) CREATE src/app/my-lifecycle-sample/my-lifecycle-sample.html (35 bytes)
步骤 2: 在组件中添加所有生命周期钩子并记录日志消息:
MyLifecycleSample.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-my-lifecycle-sample',
imports: [],
templateUrl: './my-lifecycle-sample.html',
styleUrl: './my-lifecycle-sample.css',
})
export class MyLifecycleSample {
ngOnChanges() {
console.log("变更检测") // Change detection
}
ngOnInit() {
console.log("组件/指令的初始化") // Initialization of component / directive
}
ngDoCheck() {
console.log("自定义变更检测") // Custom change detection
}
ngAfterContentInit() {
console.log("内容初始化") // Content initialization
}
ngAfterContentChecked() {
console.log("检查内容中的变更") // Checking changes in content
}
ngAfterViewInit() {
console.log("视图初始化") // View initialization
}
ngAfterViewChecked() {
console.log("检查视图中的变更") // Checking changes in views
}
ngOnDestroy() {
console.log("组件/指令的销毁") // Destruction of component / directive
}
}
步骤 3: 将组件添加到 app 组件模板 app.component.html 中。
<h1>Expense Management Application</h1> <app-expense-entry></app-expense-entry> <app-my-lifecycle-sample></app-my-lifecycle-sample> <router-outlet />
使用 ng serve 运行应用程序,并在浏览器开发者工具中测试控制台。它将显示所有生命周期事件按照上述讨论的顺序执行。
Angular 组件生命周期多选题
在本节中,通过回答以下问题来测试您对 Angular 组件生命周期的理解 −
问题 1 - 当 Angular 组件被实例化时,第一个被调用的生命周期钩子是什么?
A - ngOnInit
B - ngOnChanges
C - ngDoCheck
D - Constructor
答案:D
解释
当 Angular 首次实例化组件时,构造函数会运行。它是变更检测和初始化之前的第一阶段。
问题 2 - 哪个生命周期钩子在组件内容初始化后被调用?
A - ngAfterContentChecked
B - ngAfterContentInit
C - ngAfterViewChecked
D - ngOnInit
答案:B
解释
ngAfterContentInit() 生命周期钩子仅在组件内容中所有嵌套子元素初始化后调用一次。
问题 3 - 关于 ngDoCheck() 以下哪项是正确的?
A - 仅在输入属性发生变更时被调用。
B - 在 ngOnInit() 之后运行,用于自定义变更检测。
C - 用于内容初始化。
D - 在组件销毁后被调用。
答案:B
解释
ngDoCheck() 用于自定义变更检测,并在 ngOnInit() 之后运行。即使输入绑定属性没有变更,它也会被调用。