Angular 的生命周期

简介: 组件从开始建立到销毁的过程中,会经历过一系列的阶段。这就是一个生命周期,这些阶段对应着应用提供的 lifecycle hooks。那么,在 angular 中,这些 hooks 都有哪些呢?

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情


接触过 reactvue 开发的读者应该对生命周期这个概念不陌生。我们在使用 angular 开发的过程中,是避免不了的。

组件从开始建立到销毁的过程中,会经历过一系列的阶段。这就是一个生命周期,这些阶段对应着应用提供的 lifecycle hooks


那么,在 angular 中,这些 hooks 都有哪些呢?了解它们,对你编写程序应该在哪里编写,很重要。


angular 中,生命周期执行的顺序如下:


- constructor 【常用,不算钩子函数,但是很重要】
- ngOnChanges【常用】
- ngOnInit【常用】
- ngDoCheck
  - ngAfterContentInit
  - ngAfterContentChecked
  - ngAfterViewInit【常用】
  - ngAfterViewChecked
- ngOnDestroy【常用】
复制代码


为了解说和验证,我们用 angular-cli 生成一个 demo 项目。


constructor



es6 中的 class 初始化对象的时候,constructor 会立即被调用。


class Person {
  constructor(name) {
    console.log('be called')
    this.name = name;
  }
}
let jimmy = new Person('jimmy'); // be called
复制代码


angular 的组件本身就是导出一个类。当这个组件被 new 起来的时候,会获取 constructor 中的预设的值。


ngOnChanges



当我们有外部参数更改的时候,我们就会执行 ngOnChanges,也就是说组件中有 @Input 所绑定的属性值发生改变的时候调用。


简单说,父组件绑定子组件中的元素,会触发这个钩子函数,可以多次出发。这在下面的 ngOnInit 总会介绍。


ngOnInit



这个方法调用的时候,说明组件已经初始化成功。在第一次 ngOnChanges() 完成之后调用,且只调用一次。


// app.component.ts
export class AppComponent implements OnInit, OnChanges {
  constructor() {
    console.log('1. constructor')
  }
  ngOnChanges() {
    console.log('2. ngOnChanges')
  }
  ngOnInit() {
    console.log('3. ngOnInit')
  }
}
复制代码


打印的信息如下:


image.png


咦?怎么没有打印 ngOnChanges 中的钩子函数信息呢?


上面已经说过了,需要触发条件 @Input 的属性值改变的时候。我们来修改一下:


<!-- app.component.html -->
<div>
  <app-demo></app-demo>
</div>
复制代码


// app.component.ts
// AppComponent 类中添加属性
public count:number = 0;
复制代码


<!-- demo.component.html -->
<h3>count: {{ count }}</h3>
复制代码


// demo.component.ts
export class DemoComponent implements OnInit, OnChanges {
  @Input()
  public count: number;
  constructor() {
    console.log('1. demo constructor')
  }
  ngOnChanges() {
    console.log('2. demo ngOnChanges')
  }
  ngOnInit() {
    console.log('3. demo ngOnInit')
  }
}
复制代码


image.png


当通过 @Input 将值传递给子组件 demo 的时候,就会触发 demo 组件中的 ngOnChanges


@Input 传递的属性发生改变的时候,可以多次触发 demo 组件中的 ngOnChanges 钩子函数。


<!-- app.component.html -->
<div>
  <app-demo [count]="count"></app-demo>
  <button (click)="parentDemo()">parent button</button>
</div>
复制代码


// app.component.ts
parentDemo() {
  this.count++;
}
复制代码


image.png


ngDoCheck



当发生变化检测的时候,触发该钩子函数。


这个钩子函数,紧跟在每次执行变更检测时候 ngOnChanges 和首次执行执行变更检测时 ngOnInit 后面调用。


// demo.component.ts
ngDoCheck() {
  console.log('4. demo ngDoCheck')
}
复制代码


image.png


这个钩子函数调用得比较频繁,使用成本比较高,谨慎使用。


一般使用 ngOnChanges 来检测变动,而不是 ngDoCheck


ngAfterContentInit



当把外部的内容投影到内部组件,第一次调用 ngDoCheck 之后调用 ngAfterContentInit,而且只调用一次。


// demo.component.ts
ngAfterContentInit() {
  console.log('5. demo ngAfterContentInit');
}
复制代码



image.png


ngAfterContentChecked



ngAfterContentChecked 钩子函数在每次 ngDoCheck 之后调用.


// demo.component.ts
ngAfterContentChecked() {
  console.log('5. demo ngAfterContentChecked');
}
复制代码


image.png


ngAfterViewInit



视图初始化完成调用此钩子函数。在第一次 ngAfterContentChecked 之后调用,只调用一次。


这个时候,获取页面的 DOM 节点比较合理


// demo.compoent.ts
ngAfterViewInit() {
  console.log('7. demo ngAfterViewInit');
}
复制代码


image.png


ngAfterViewChecked



视图检测完成调用。在 ngAfterViewinit 后调用,和在每次 ngAfterContentChecked 之后调用,也就是在每次 ngDoCheck 之后调用。


// demo.component.ts
ngAfterViewChecked() {
  console.log('8. ngAfterViewChecked')
}
复制代码


image.png

ngOnDestroy



组件被销毁时候进行的操作。


在这个钩子函数中,我们可以取消订阅,取消定时操作等等。


<!-- app.component.html -->
<app-demo [count]="count" *ngIf="showDemoComponent"></app-demo>
<button (click)="hideDemo()">hide demo component</button>
复制代码


// app.component.ts
public showDemoComponent: boolean = true;
hideDemo() {
  this.showDemoComponent = false
}
复制代码


// demo.component.ts
ngOnDestroy() {
  console.log('9. demo ngOnDestroy')
}
复制代码


image.png


PS: 不知道读者有没有发现,调用一次的钩子函数都比较常用~


相关文章
|
11天前
angular生命周期钩子
angular生命周期钩子
Angular 2 组件的生命周期简要
接口 OnInit OnDestroy DoCheck OnChanges AfterContentInit AfterContentChecked AfterViewInit AfterViewChecked 函数名 ngOnChanges - 当输...
827 0
Angular2生命周期钩子函数
Angular每个组件都存在一个生命周期,从创建,变更到销毁。Angular提供组件生命周期钩子,把这些关键时刻暴露出来,赋予在这些关键结点和组件进行交互的能力,掌握生命周期,可以让我们更好的开发Angular应用 概述 每个接口都有唯一的一个钩子方法,它们的名字是由接口名再加上ng前缀构成的。
1064 0
|
6天前
|
缓存 JavaScript 前端开发
Angular 应用打包和部署
Angular 应用打包和部署
23 1
|
19天前
|
应用服务中间件 Java Maven
掌控视图的力量!深入解析 JSF 视图管理,揭秘视图生命周期的秘密,让你的应用更高效!
【8月更文挑战第31天】JavaServer Faces (JSF) 是一种强大的框架,用于管理 Web 应用程序的视图。本文通过具体案例介绍 JSF 视图管理的基础知识,包括创建、管理和销毁视图的过程。首先,在 Eclipse 中创建一个新 JSF 项目,并配置 Maven 依赖。接着,在 `WEB-INF` 目录下配置 `web.xml` 文件,设置 JSF servlet。
31 0
|
19天前
|
Java Spring
🔥JSF 与 Spring 强强联手:打造高效、灵活的 Web 应用新标杆!💪 你还不知道吗?
【8月更文挑战第31天】JavaServer Faces(JSF)与 Spring 框架是常用的 Java Web 技术。本文介绍如何整合两者,发挥各自优势,构建高效灵活的 Web 应用。首先通过 `web.xml` 和 `ContextLoaderListener` 配置 Spring 上下文,在 `applicationContext.xml` 定义 Bean。接着使用 `@Autowired` 将 Spring 管理的 Bean 注入到 JSF 管理的 Bean 中。
30 0
|
19天前
|
开发者 Java 开发框架
JSF与EJB,打造企业级应用的神器!让你的Web应用更加稳定、高效!
【8月更文挑战第31天】在现代企业级应用开发中,JSF(JavaServer Faces)与EJB(Enterprise JavaBeans)是两大核心技术。JSF作为一款基于Java的Web应用框架,以其丰富的UI组件和表单处理功能著称;EJB则专注于提供分布式事务处理及远程调用等企业级服务。两者的结合为企业应用带来了高效便捷的开发模式。下文将通过一个简单的示例展示如何利用JSF进行用户信息的输入与保存,并借助EJB实现相关业务逻辑。尽管这一组合具有明显优势,但在实际应用中还需考虑其局限性并作出合理选择。
33 0
|
19天前
|
开发者 安全 SQL
JSF安全卫士:打造铜墙铁壁,抵御Web攻击的钢铁防线!
【8月更文挑战第31天】在构建Web应用时,安全性至关重要。JavaServer Faces (JSF)作为流行的Java Web框架,需防范如XSS、CSRF及SQL注入等攻击。本文详细介绍了如何在JSF应用中实施安全措施,包括严格验证用户输入、使用安全编码实践、实施内容安全策略(CSP)及使用CSRF tokens等。通过示例代码和最佳实践,帮助开发者构建更安全的应用,保护用户数据和系统资源。
32 0
|
19天前
|
容器 iOS开发 Linux
震惊!Uno Platform 响应式 UI 构建秘籍大公开!从布局容器到自适应设计,带你轻松打造跨平台完美界面
【8月更文挑战第31天】Uno Platform 是一款强大的跨平台应用开发框架,支持 Web、桌面(Windows、macOS、Linux)及移动(iOS、Android)等平台,仅需单一代码库。本文分享了四个构建响应式用户界面的最佳实践:利用布局容器(如 Grid)适配不同屏幕尺寸;采用自适应布局调整 UI;使用媒体查询定制样式;遵循响应式设计原则确保 UI 元素自适应调整。通过这些方法,开发者可以为用户提供一致且优秀的多设备体验。
32 0