angular开发详解(详解Angular组件生命周期一)
angular开发详解
详解Angular组件生命周期一目录
- 概述
- 一、钩子的调用顺序
- 二、onChanges钩子
- 三、变更检测机制和DoCheck()钩子
组件声明周期以及angular的变化发现机制
红色方法只执行一次。
变更检测执行的绿色方法和和组件初始化阶段执行的绿色方法是一个方法。
总共9个方法。
每个钩子都是@angular/core库里定义的接口。
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-life', templateUrl: './life.component.html', styleUrls: ['./life.component.css'] }) export class LifeComponent implements OnInit { constructor() { } ngOnInit() { } }
虽然接口不是必须的,Angular检测到钩子方法就会去执行它,还是建议把接口写上。
一、钩子的调用顺序import { Component, OnInit, OnChanges, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy, Input, SimpleChange, SimpleChanges } from '@angular/core'; let logIndex: number = 1; //计数器 @Component({ selector: 'app-life', templateUrl: './life.component.html', styleUrls: ['./life.component.css'] }) export class LifeComponent implements OnInit, OnChanges, DoCheck, AfterContentInit , AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy { @Input() name: string; logIt(msg: string) { console.log(`# ${logIndex++} ${msg}`); } constructor() { this.logIt("name属性在constructor里的值是: " + this.name); } ngOnInit() { this.logIt("name属性在OnInit里的值是: " + this.name); } ngOnChanges(changes: SimpleChanges): void { // 传入一个SimpleChanges对象 let name = changes['name'].currentValue; this.logIt("name属性在ngOnChanges里的值是: " + this.name); } ngDoCheck(): void { this.logIt("DoCheck"); } ngAfterContentInit() { this.logIt("ngAfterContentInit"); } ngAfterContentChecked() { this.logIt("ngAfterContentChecked"); } ngAfterViewInit() { this.logIt("ngAfterViewInit"); } ngAfterViewChecked() { this.logIt("ngAfterViewChecked"); } ngOnDestroy() { this.logIt("ngOnDestory"); } }
初始化逻辑依赖输入属性的值时,初始化逻辑一定要写在ngOnInit里,不能写在constructor里面。
DoCheck在Angular的每个变更检测周期中调用。
ngAfterContentInit和ngAfterContentChecked跟模版,组件的内容投影相关的。
ngAfterViewInit和ngAfterViewChecked跟组件的模版,初始化视图相关的。
二、onChanges钩子父组件初始化或修改子组件的输入参数时会被调用。
需要先理解js中可变对象 和 不可变对象。
//字符串是不可变的 var greeting = "Hello"; greeting = "Hello World"; //对象是可变的 var user = { name: "Tom" }; user.name = "Jerry";
例子:
child组件有3个属性,其中2个是输入属性。
父组件有一个greeting属性和一个name属性是Tom的user对象。
父组件要改变输入属性,所以greeting和user.name是双向绑定。
<li class="parent"> <h2>我是父组件</h2> <li>问候语:<input type="text" [(ngModel)]="greeting"></li> <li> 姓名: <input type="text" [(ngModel)]="user.name"> </li> <app-child [greeting]="greeting" [(user)]="user"> </app-child> </li>
父组件改变两个input的值,值变化时候传入子组件的值也会变化,传入子组件的输入属性的值变化时会触发ngOnChanges()。
父组件初始化子组件。初始化的时候调一次ngOnChanges(),初始化后子组件的greeting变成Hello,也就是父组件上的greeting的值。
user变成一个name属性为Tom的对象。
改变输入属性的值,父组件问候语greeting改为Helloa。
Angular的变更检测刷新不可变对象,也就是greeting的值,然后调用ngOnChanges()方法,greeting的值从之前的hello,变为了Helloa。
修改user.name为Tomb,控制台上没有打印新的消息。
因为用户只是改变了可变对象user的属性,user对象的引用自身是没有改变的,所以onChanges()方法没有被调用。
虽然可变对象的属性改变不会触发ngOnChanges()方法调用,但是子组件的user对象的属性仍然改变了,由于Angular的变更监测机制仍然捕获了组件中每个对象的属性变化。
改变子组件的message属性也不引起子组件的onChanges()方法调用。因为message不是输入属性。而ngOnChanges()只有在输入属性变化时候被调用。
三、变更检测机制和DoCheck()钩子变更检测由zone.js实现的。保证组件的属性变化和页面的变化同步。浏览器中发生的异步事件(点击按钮,输入数据,数据从服务器返回,调用了setTimeout()方法)都会触发变更检测。
变更检测运行时,检测组件模版上的所有绑定关系,如果组件属性被改变,与其绑定的模版相应区域可能需要更新。
注意:变更检测机制只是将组件属性的改变反应到模版上,变更检测机制本身永远不会改变组件属性的值。
两种变更检测策略。
- Default 检测到变化,检查整个组件树。
- OnPush 只有当输入属性变化时,才去检测该组件及其子组件。
Angular应用是一个以主组件为根的组件树,每个组件都会生成一个变更检测器,任何一个变更检测器检测到变化,zone.js就根据组件的变更检查策略来检测组件(也就是调doCheck()钩子),来判断组件是否需要更新它的模版。
DoCheck检查是从根组件开始往下检查所有的组件树,不管变更发生在哪个组件。
例子:
监控user.name这种可变对象的属性的改变。
在child中加一个oldUsername来存变更前的username,加一个changeDetected属性标志username是否发生变化,默认是false。 noChangeCount计数器默认是0。
import { Component, OnInit, Input, OnChanges, SimpleChanges, DoCheck } from '@angular/core'; @Component({ selector: 'app-child', templateUrl: './child.component.html', styleUrls: ['./child.component.css'] }) export class ChildComponent implements OnInit, OnChanges, DoCheck { @Input() greeting: string; @Input() user: { name: string }; message: string = "初始化消息"; oldUsername: string; changeDetected: boolean = false; noChangeCount: number = 0; constructor() { } ngOnInit() { } ngOnChanges(changes: SimpleChanges): void { console.log(JSON.stri.jpg" alt="angular开发详解(详解Angular组件生命周期一)" border="0" />
页面加载完成:user.name没变化时DoCheck方法已经被调用1次。
鼠标点击,不改变任何值,点击触发变更检测机制,所有组件的DoCheck就会被调用。
修改Tom为Tomb,DoCheck捕捉到Tom变为Tomb。
虽然DoCheck()钩子可以检测到user.name什么时候发生变化,但是使用必须小心,ngDoCheck()钩子被非常频繁的调用。每次变更检测周期后发生变化的地方都会调用。
对ngDoCheck()的实现必须非常高效,非常轻量级,否则容易引起性能问题。
同理:所有带Check关键字的钩子方法都要非常小心。 ngDoCheck,ngAfterContentChecked,ngAfterViewChecked.
以上就是详解Angular组件生命周期(一)的详细内容,更多关于Angular组件生命周期的资料请关注开心学习网其它相关文章!
- angularjs数据绑定类指令及作用(详解Angular数据绑定及其实现方式)
- angular兄弟组件调用方法(Angular封装WangEditor富文本组件的方法)
- angular怎么创建声明(使用Angular CDK实现一个Service弹出Toast组件功能)
- angular定义一个管道(Angular管道PIPE的介绍与使用方法)
- angular路由树(详解Angular路由之子路由)
- angular怎么把组件用在根组件里(详解Angular组件之投影)
- angular开发详解(详解Angular组件生命周期一)
- vue react和angular(详解React Angular Vue三大前端技术)
- angular简单介绍(详解Angular依赖注入)
- angular 常用模块(详解Angular之路由基础)
- angular使用方法(Angular环境搭建及简单体验小结)
- angular模块的组成(详解Angular结构型指令模块和样式)
- angular封装进度条组件(如何用DevUI搭建自己的Angular组件库)
- angular教程第九讲(浅谈Angular的12个经典问题)
- angular引入组件库(详解Angular组件之中间人模式)
- angular开发详解(详解Angular动态组件)
- 这里输入关键词(如何输入关键词)
- 熊猫中国国宝(熊猫国宝酒53酱香)
- 春节会放假几天(春节会放假吗)
- 小浴室,大民生 缙云3200多户困难群众洗上免费热水澡(小浴室大民生缙云3200多户困难群众洗上免费热水澡)
- 元旦闲谭(元旦闲谭)
- 息烽 这个村 治垃圾 有招 人人争当卫生模范(息烽这个村治垃圾)
热门推荐
- mysql索引详解及基本用法(Mysql普通索引与唯一索引的选择详析)
- php开发技巧和方法(php+ajax实现商品对比功能示例)
- 织梦dedecms开启付费授权(织梦dedeCMS二次开发文档手册 程序目录详解以及数据表结构字段)
- css图片水平旋转动画(css实现图片横向排列滚动效果)
- nginx启动报错连接失败(宝塔面板Nginx环境中出现404 Not Found的解决方法)
- extjs checkboxGroup 复选框的用法
- numpy常用统计分析函数(Numpy之random函数使用学习)
- css3动画效果图(css3实现波纹特效、H5实现动态波浪效果)
- dockerfile挂载目录(解决docker run中使用 ./ 相对路径挂载文件或目录失败的问题)
- 怎么查看mysql计划执行情况(详解 MySQL 执行计划)