Angular Component组件的生命周期(一)
Angular Component组件的生命周期按时间次序可以分为以下阶段:
- 组件的生命周期是从Angular 实例化组件开始
- 接着渲染组件的视图以及子组件视图
- 完成组件视图渲染后,Angular仍然会检测组件的变化,主要包括
- 检测绑定属性的变化(change detect)
- 根据检测到的变化,如果有必要,则更新组件和它的子组件
- Component组件生命周期结束最终是销毁组件,以及从DOM中移除组件的模板
有些场景,我们需要在Component组件的某个阶段,如检测到属性变化,介入做一些处理。Angular提供了8个生命周期接口方法,允许我们可以对Component组件的运行做细粒度的控制。这些Component组件的生命周期方法,称之为lifecycle hook。
按调用顺序自上而下的hook方法:
<figure class="image"></figure>其中:ngAfterContentInit,ngAfterContentChecked,ngAfterViewInit和ngAfterViewChecked是组件对子组件视图或内容的变化检测调用。
constructor
Angular调用构造函数实例化Component组件。构造函数主要完成的是依赖注入,尽量保持它比较轻量,不要在这里写复杂或耗时的代码。
ngOnChanges
Angular检测到绑定属性变化会调用ngOnChanges方法。绑定属性指的是使用@Input标记的属性。
在以下两种情况下会被认为是绑定属性发生了变化:
- 对@Input标记的属性设置赋值
- 对@Input标记的属性重置值。
如果Component组件没有绑定Input属性,那么就不会调用ngOnChanges方法。
赋值绑定属性调用ngOnChanges
对于首次赋值给绑定的属性,Angular会在调用ngOnInit()
之前调用ngOnChanges.
重置绑定属性的值调用ngOnChanges
需要特别注意理解什么是重置值。
这种情况不是重置:
let user:User = new User("张三");
user.name = “李四”;
这是对user的name进行修改,但没有对user重置值。
let user:User = new User("张三");
user = new User(“李四”);
这个表示重置user的值。
实现OnChanges接口
要在Angular检测到绑定属性变化调用ngOnChanges方法,需要实现OnChanges接口。
import { Component, EventEmitter, Input, OnChanges,SimpleChanges } from '@angular/core';
…
@Component{
selector: 'demo',
templateUrl: './demo.component.html',
styleUrls: ['./demo.component.scss']
}
export class DemoComponet implements OnChanges {
ngOnChanges(changes: SimpleChanges): void {
// do something
}
}
SimpleChanges:变化内容的传递
ngOnChanges会接收SimpleChanges的参数,它实际是一个map。SimpleChanges定义如下
export declare interface SimpleChanges {
[propName: string]: SimpleChange;
}
SimpleChange定义:
class SimpleChange {
constructor(previousValue: any, currentValue: any)
previousValue : any
currentValue : any
isFirstChange() : boolean
}
- previousValue:表示发生变化之前的值
- currentValue:变化后当前的值
- isFirstChange:首次赋值,此值为true,后面重置值则时false。
当绑定属性的值发生变化,Angular会把变化的属性对应的SimpleChange传给ngOnChanges。对应Component组件绑定多个Input属性,changes参数只会传发生变化的值,没有变化的值不会传递。
示例:
ngOnChanges(changes: SimpleChanges) {
for (let key in changes) {
console.log(`${key} changed.
Current: ${changes[key].currentValue}.
Previous: ${changes[key].previousValue}`);
}
}
ngOnInit
ngOnInit是在Component组件完成首次对@Input标记的属性赋值后调用,即首次调用ngOnChanges方法后,才会调用ngOnIit,并且只会调用一次。
好的编程习惯是把复杂的初始化工作放在构造函数constructor外,构造函数应该保持简单,只用来初始化一些本地变量。特别是需要通过调用远程服务来初始化数据,这些内容不应放在构造函数中。
Angular提供了OnInit接口,由它的接口方法ngOnInit来完成一些复杂的初始化工作。比如从远程服务中获取数据。
示例:
import { Component, EventEmitter, Input, OnInit } from '@angular/core';
…
@Component{
selector: 'demo',
templateUrl: './demo.component.html',
styleUrls: ['./demo.component.scss']
}
export class DemoComponet implements OnInit {
ngOnInit(): void {
// do something
}
}