浅谈对Angular中的生命周期钩子的理解


Posted in Javascript onJuly 31, 2017

本文介绍了Angular中的生命周期钩子的理解,分享给大家,希望对大家有所帮助

什么是生命周期钩子

简单点来说生命周期钩子就是Angular中一个组件从被创建当销毁期间的一些有意义的关键时刻.这些关键时刻在Angular中被Angular核心模块 @angular/core 暴露出来,赋予了我们在它们发生时采取行动的能力.

有哪些生命周期钩子

Angular中从一个组件的创建到销毁一个有八个生命周期钩子它们,按照先后顺序.它们分别是:

  1. ngOnChanges()
  2. ngOnInit()
  3. ngDoCheck()
  4. ngAfterContentInit()
  5. ngAfterContentChecked()
  6. ngAfterViewInit()
  7. ngAfterViewChecked()
  8. ngOnDestroy()

其中: ngOnInit() 、 ngAfterContentInit() 、 ngAfterViewInit() 和 ngOnDestroy() 在一个组件的生命周期中只会被调用一次,其它的都有可能会被多次调用.下面,就让我们来详细解列一下这些生命周期钩子.

ngOnChanges()

  • 当Angular(重新)设置数据绑定输入属性时响应。 该方法接受当前和上一属性值的SimpleChanges对象
  • 当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在ngOnInit()之前。

ngOnChanges() 生命周期的调用与一个组件中的输入属性有关.

当在一个组件中使用 @Input() 定义了一个输入属性时.只要这个输入属性的值发生了改变.就会触发 ngOnChanges() 生命周期钩子.这个生命周期钩子被调用时会传入一个 SimpleChanges 对象,这个对象中包含了输入属性当前值和上一值.

@Input()
public name: string;

ngOnChanges(changes: SimpleChanges): void {
 console.log(changes); // name:SimpleChange {previousValue: "a", currentValue: "ab", firstChange: false}
}

上面是我定义了一个输入属性 name 并将从 a 它改为 ab 之后的打印结果,可能你还注意到了打印的结果中还有一个 firstChange 属性.它是一个Booleans,表明你是否是第一次改变.

同时,还有一点需要注意:你的输入属性定义为你引用类型和基本类型的时候其表现结果是不同的.当你的输入属性是基本类型时.你的每一次改变都会触发 ngOnChanges() 生命周期钩子,而当你的输入属性是引用类型时,你改变你引用类型 当中 的属性时,并不会触发 ngOnChanges() 生命周期钩子.只有当你将你引用类型数据的指针指向另一块内存地址的时候才会触发 ngOnChanges() 生命周期钩子.

ngOnInit()

  • 在Angular第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。
  • 在第一轮ngOnChanges()完成之后调用,只调用一次。

ngOnInit() 是一个组件的生命周期中一定存在的一个钩子.它在一个组件被初始化的时候被调用.在这个期间,你可以执行一些相应的数据绑定操作.

ngDoCheck()

  • 检测,并在发生Angular无法或不愿意自己检测的变化时作出反应。
  • 在每个Angular变更检测周期中调用,ngOnChanges()和ngOnInit()之后。

ngDoCheck() 是Angular中的变更检测机制.它由 zone.js 来实现的.其行为是只要你的Angular中的某个组件发生异步事件.就会检查整个组件树,以保证组件属性的变化或页面的变化是同步的.所以 ngDoCheck() 的触发相当频繁的.并且是我们无法预料到的.也许我们在页面上的一个无意识操作,就会触发几个甚至几十个的 ngDoCheck() 生命周期钩子.

所以我们在使用 ngDoCheck() 生命周期钩子的时候一定要加上判断.以避免无用的触发干扰我们.

ngAfterContentInit()

  • 当把内容投影进组件之后调用。
  • 第一次ngDoCheck()之后调用,只调用一次。
  • 只适用于组件。

当父组件向子组件投影内容的时.在子组件内会初始化父组件的投影内容,此时会调用 ngAfterContentInit() 生命周期钩子.在整个组件生命周期中 ngAfterContentInit() 生命周期钩子只会调用一次.如下所示:

// 父组件
<app-child>
 <p>我是父组件向子组件的投影内容</>
</app-child>


// 子组件 ChildComponent
<div>
 //接受父组件的投影内容
 <ng-content></ng-content>
</div>

ngAfterContentChecked()

  • 每次完成被投影组件内容的变更检测之后调用。
  • ngAfterContentInit()和每次ngDoCheck()之后调用
  • 只适合组件。

当父组件向子组件的投影内容发生改变时会调用 ngAfterContentChecked() 生命周期钩子.它与 ngDoCheck() 类似.当投影内容发生改变时,就会执行变更检查机制.同时调用 ngAfterContentChecked() 生命周期钩子.此外.还有一点:当父组件和子组件都有投影内容时,会先执行父组件的生命周期钩子.它与下面要说的 ngAfterViewInit() 和 ngAfterViewChecked() 相反.

ngAfterViewInit()

  • 初始化完组件视图及其子视图之后调用。
  • 第一次ngAfterContentChecked()之后调用,只调用一次。
  • 只适合组件。

当其组件本身和所有的子组件渲染完成,已经呈现在页面上时,调用 ngAfterViewInit() 生命周期钩子.在整个组件生命周期中 ngAfterViewInit() 生命周期钩子只会调用一次.

ngAfterViewChecked()

  • 每次做完组件视图和子视图的变更检测之后调用。
  • ngAfterViewInit()和每次ngAfterContentChecked()之后调用。
  • 只适合组件。

当组件及其子组件的视图发生改变时,执行完变更检查机制后调用.当父组件和子组件都发生视图变化时,会先执行子组件的生命周期钩子.

注意:这里所说的视图发生改变不一定是真正页面上的变化.只是Angular种所认为的视图变化.因为Angular本身并不能察觉到页面上显示的视图.所以在Angular认为,只要你在后台定义的属性发生了改变,就是视图有了变化.从而就会调用 ngAfterViewChecked() 生命周期钩子.

ngOnDestroy

  • 当Angular每次销毁指令/组件之前调用并清扫。 在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏。
  • 在Angular销毁指令/组件之前调用。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
一款js和css代码压缩工具[附JAVA环境配置方法]
Apr 16 Javascript
修改jquery.lazyload.js实现页面延迟载入
Dec 22 Javascript
五个jQuery图片画廊插件 推荐
May 12 Javascript
图片img的src不变让浏览器重新加载实现方法
Mar 29 Javascript
js整数字符串转换为金额类型数据(示例代码)
Dec 26 Javascript
JavaScript省市联动实现代码
Feb 15 Javascript
assert()函数用法总结(推荐)
Jan 25 Javascript
基于jQuery实现的设置文本区域的光标位置
Jun 15 jQuery
angularjs通过过滤器返回超链接的方法
Oct 26 Javascript
Js视频播放器插件Video.js使用方法详解
Feb 04 Javascript
通过angular CDK实现页面元素拖放的步骤详解
Jul 01 Javascript
详解React中共享组件逻辑的三种方式
Feb 02 Javascript
Bootstrap Table 在指定列中添加下拉框控件并获取所选值
Jul 31 #Javascript
vue组件 $children,$refs,$parent的使用详解
Jul 31 #Javascript
Kindeditor单独调用单图上传增加预览功能的实例
Jul 31 #Javascript
Kindeditor单独调用多图上传实例
Jul 31 #Javascript
老生常谈ES6中的类
Jul 31 #Javascript
JS时间控制实现动态效果的实例讲解
Jul 31 #Javascript
JavaScript实现简单的双色球(实例讲解)
Jul 31 #Javascript
You might like
PHP延迟静态绑定示例分享
2014/06/22 PHP
PHP中的命名空间详细介绍
2015/07/02 PHP
PHP判断密码强度的方法详解
2017/05/26 PHP
PHP SESSION机制的理解与实例
2019/03/22 PHP
Three.js源码阅读笔记(基础的核心Core对象)
2012/12/27 Javascript
jQueryMobile之Helloworld与页面切换的方法
2015/02/04 Javascript
js绘制圆形和矩形的方法
2015/08/05 Javascript
学习JavaScript设计模式(代理模式)
2015/12/03 Javascript
JavaScript快速切换繁体中文和简体中文的方法及网站支持简繁体切换的绝招
2016/03/07 Javascript
基于JS代码实现图片在页面中旋转效果
2016/06/16 Javascript
深入理解requestAnimationFrame的动画循环
2016/09/20 Javascript
使用Require.js封装原生js轮播图的实现代码
2017/06/15 Javascript
Vue-Router实现组件间跳转的三种方法
2017/11/07 Javascript
ios设备中angularjs无法改变页面title的解决方法
2018/09/13 Javascript
Vue源码中要const _toStr = Object.prototype.toString的原因分析
2018/12/09 Javascript
jquery实现选项卡切换代码实例
2019/05/14 jQuery
[03:34]2014DOTA2西雅图国际邀请赛 淘汰赛7月15日TOPPLAY
2014/07/15 DOTA
[01:02:46]VGJ.S vs NB 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
利用Python破解斗地主残局详解
2017/06/30 Python
python matplotlib画图库学习绘制常用的图
2019/03/19 Python
利用python和百度地图API实现数据地图标注的方法
2019/05/13 Python
Python使用ElementTree美化XML格式的操作
2020/03/06 Python
python产生模拟数据faker库的使用详解
2020/11/04 Python
Snapfish爱尔兰:在线照片打印和个性化照片礼品
2018/09/17 全球购物
物业管理应届生求职信
2013/10/28 职场文书
淘宝活动策划方案
2014/02/06 职场文书
财务支持类个人的自我评价
2014/02/14 职场文书
党委班子剖析材料
2014/08/21 职场文书
2014年工会工作总结
2014/11/12 职场文书
2014年维修工作总结
2014/11/22 职场文书
商务英语求职信范文
2015/03/19 职场文书
力克胡哲观后感
2015/06/10 职场文书
休假证明书
2015/06/24 职场文书
简单介绍 http请求响应参数、无连接无状态、MIME、状态码、端口、telnet、curl
2021/03/31 HTML / CSS
MySQL命令无法输入中文问题的解决方式
2021/08/30 MySQL
PostgreSQL数据库创建并使用视图以及子查询
2022/04/11 PostgreSQL