每一個組件都有一個被 Angular 管理的生命週期。javascript
Angular 建立它,渲染它,建立並渲染它的子組件,在它被綁定的屬性發生變化時檢查它,並在它從 DOM 中被移除前銷燬它。css
Angular 提供了生命週期鉤子,把這些關鍵生命時刻暴露出來,賦予你在它們發生時採起行動的能力。html
除了那些組件內容和視圖相關的鉤子外,指令有相同生命週期鉤子。java
ngOnChanges() | 當 Angular(從新)設置數據綁定輸入屬性時響應。 該方法接受當前和上一屬性值的 SimpleChanges 對象app 當被綁定的輸入屬性的值發生變化時調用,首次調用必定會發生在 |
ngOnInit() | 在 Angular 第一次顯示數據綁定和設置指令/組件的輸入屬性以後,初始化指令/組件。this 在第一輪 |
ngDoCheck() | 檢測,並在發生 Angular 沒法或不肯意本身檢測的變化時做出反應。3d 在每一個 Angular 變動檢測週期中調用, |
ngAfterContentInit() | 當把內容投影進組件以後調用。 第一次 |
ngAfterContentChecked() | 每次完成被投影組件內容的變動檢測以後調用。
|
ngAfterViewInit() | 初始化完組件視圖及其子視圖以後調用。 第一次 |
ngAfterViewChecked() | 每次作完組件視圖和子視圖的變動檢測以後調用。
|
ngOnDestroy() | 當 Angular 每次銷燬指令/組件以前調用並清掃。 在這兒反訂閱可觀察對象和分離事件處理器,以防內存泄漏。 在 Angular 銷燬指令/組件以前調用。 |
// test2.component.ts:
import { Component, OnInit,Input } from '@angular/core'; @Component({ selector: 'app-test2', templateUrl: './test2.component.html', styleUrls: ['./test2.component.css'] })
//須要繼承 OnInit、OnChanges 接口 export class Test2Component implements OnInit OnChanges{
// 兩個input 來自 父組件 test1 @Input() test2_value1: string; @Input() test2_value2: string; constructor() { } ngOnInit() {
//判斷 ngOnInit的執行順序 console.log("這裏執行ngOnInit"); } ngOnChanges(changes:SimpleChanges){ console.log(changes); for (let propName in changes) { let chng = changes[propName]; let cur = JSON.stringify(chng.currentValue); let prev = JSON.stringify(chng.previousValue); console.log(`${propName}: 新值 = ${cur}, 舊值 = ${prev}`); } } }
<!-- test1.component.html --> <p> test1 works! </p> <label> test1 value</label> <input type="text" [(ngModel)]="test1_value1" > <input type="text" [(ngModel)]="test1_value2" > <!-- 將test1_value1的值給test2_value1... --> <app-test2 [test2_value1]="test1_value1" [test2_value2]="test1_value2"></app-test2>
import { Component, OnInit,Input,OnChanges,DoCheck} from '@angular/core'; @Component({ selector: 'app-test2', templateUrl: './test2.component.html', styleUrls: ['./test2.component.css'] })
//須要實現 DoCheck 接口 export class Test2Component implements OnInit OnChanges DoCheck{ @Input() test2_value1: string; @Input() test2_value2: string; constructor() { } ngOnInit() { //console.log("這裏執行ngOnInit"); } ngOnChanges(changes:SimpleChanges){ //console.log(changes); for (let propName in changes) { let chng = changes[propName]; let cur = JSON.stringify(chng.currentValue); let prev = JSON.stringify(chng.previousValue); //console.log(`${propName}: 新值 = ${cur}, 舊值 = ${prev}`); } } ngDoCheck(){ console.log("執行ngDoCheck"); } }
import { Component } from '@angular/core'; @Component({ selector: 'app-root', //templateUrl: './app.component.html', //在app主組價中,將test2組件放到test1組件中, template: `<app-test1> <app-test2></app-test2> </app-test1>`, styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app'; }
import { Component, OnInit,OnChanges} from '@angular/core'; @Component({ selector: 'app-test1', //templateUrl: './test1.component.html', //ng-content指定的是外來的組件 在組件app中定義的 test2組件 //一樣在test1組件中,也增長test2 組件 template: `<div> <ng-content></ng-content> <app-test2></app-test2> </div>`, styleUrls: ['./test1.component.css'] }) export class Test1Component implements OnInit, OnChanges{ test1_value1:string; test1_value2:string; constructor() { } ngOnInit() { this.test1_value1="1" this.test1_value2="2" } ngOnChanges(){ console.log("onchange"); } }
import { Component, OnInit,Input ,OnChanges,DoCheck,SimpleChanges,AfterContentInit} from '@angular/core'; @Component({ selector: 'app-test2', templateUrl: './test2.component.html', styleUrls: ['./test2.component.css'] }) export class Test2Component implements OnInit,OnChanges,DoCheck,AfterContentInit{ @Input() test2_value1: string; @Input() test2_value2: string; constructor() { } ngOnInit() { //console.log("這裏執行ngOnInit"); } ngOnChanges(changes:SimpleChanges){ //console.log(changes); for (let propName in changes) { let chng = changes[propName]; let cur = JSON.stringify(chng.currentValue); let prev = JSON.stringify(chng.previousValue); //console.log(`${propName}: 新值 = ${cur}, 舊值 = ${prev}`); } } ngDoCheck(){ console.log("執行ngDoCheck"); } ngAfterContentInit(){ console.log("執行ngAfterContentInit"); } }
import { Component, OnInit,Input ,OnChanges,DoCheck,SimpleChanges,AfterContentInit,AfterContentCheck} from '@angular/core'; @Component({ selector: 'app-test2', templateUrl: './test2.component.html', styleUrls: ['./test2.component.css'] }) export class Test2Component implements OnInit,OnChanges,DoCheck,AfterContentInit,AfterContentCheck{ @Input() test2_value1: string; @Input() test2_value2: string; constructor() { } ngOnInit() { //console.log("這裏執行ngOnInit"); } ngOnChanges(changes:SimpleChanges){ //console.log(changes); for (let propName in changes) { let chng = changes[propName]; let cur = JSON.stringify(chng.currentValue); let prev = JSON.stringify(chng.previousValue); //console.log(`${propName}: 新值 = ${cur}, 舊值 = ${prev}`); } } ngDoCheck(){ console.log("執行ngDoCheck"); } ngAfterContentInit(){ console.log("執行ngAfterContentInit"); } ngAfterContentChecked(){ console.log("執行ngAfterContentChecked"); } }
import { Component, OnInit,OnChanges,ViewChild} from '@angular/core'; import {Test2Component} from "../test2/test2.component" @Component({ selector: 'app-test1', //templateUrl: './test1.component.html', template: `<div> <input type="text" [(ngModel)]="test1_value1" > <input type="text" [(ngModel)]="test1_value2" ><ng-content></ng-content> <app-test2 [test2_value1]="test1_value1" [test2_value2]="test1_value2"></app-test2> </div>`, styleUrls: ['./test1.component.css'] }) export class Test1Component implements OnInit, OnChanges{ test1_value1:string; test1_value2:string; constructor() { } @ViewChild(Test2Component); ngOnInit() { this.test1_value1="1" this.test1_value2="2" } ngOnChanges(){ console.log("onchange"); } }
import { Component, OnInit,Input ,OnChanges,DoCheck,SimpleChanges,AfterContentInit,AfterContentCheck, AfterViewChecked, AfterViewInit} from '@angular/core'; @Component({ selector: 'app-test2', templateUrl: './test2.component.html', styleUrls: ['./test2.component.css'] }) export class Test2Component implements OnInit,OnChanges,DoCheck,AfterContentInit,AfterContentCheck ,AfterViewChecked, AfterViewInit{ @Input() test2_value1: string; @Input() test2_value2: string; constructor() { } ngOnInit() { //console.log("這裏執行ngOnInit"); } ngOnChanges(changes:SimpleChanges){ //console.log(changes); for (let propName in changes) { let chng = changes[propName]; let cur = JSON.stringify(chng.currentValue); let prev = JSON.stringify(chng.previousValue); //console.log(`${propName}: 新值 = ${cur}, 舊值 = ${prev}`); } } ngDoCheck(){ console.log("執行ngDoCheck"); } ngAfterContentInit(){ console.log("執行ngAfterContentInit"); } ngAfterContentChecked(){ console.log("執行ngAfterContentChecked"); } ngAfterViewInit(){ console.log("執行ngAfterViewInit"); } }
import { Component, OnInit,Input ,OnChanges,DoCheck,SimpleChanges,AfterContentInit,AfterContentCheck, AfterViewChecked, AfterViewInit} from '@angular/core'; @Component({ selector: 'app-test2', templateUrl: './test2.component.html', styleUrls: ['./test2.component.css'] }) export class Test2Component implements OnInit,OnChanges,DoCheck,AfterContentInit,AfterContentCheck ,AfterViewChecked, AfterViewInit{ @Input() test2_value1: string; @Input() test2_value2: string; constructor() { } ngOnInit() { //console.log("這裏執行ngOnInit"); } ngOnChanges(changes:SimpleChanges){ //console.log(changes); for (let propName in changes) { let chng = changes[propName]; let cur = JSON.stringify(chng.currentValue); let prev = JSON.stringify(chng.previousValue); //console.log(`${propName}: 新值 = ${cur}, 舊值 = ${prev}`); } } ngDoCheck(){ console.log("執行ngDoCheck"); } ngAfterContentInit(){ console.log("執行ngAfterContentInit"); } ngAfterContentChecked(){ console.log("執行ngAfterContentChecked"); } ngAfterViewInit(){ console.log("執行ngAfterViewInit"); } ngAfterViewChecked(){ console.log("執行ngAfterViewChecked"); } }
import { Component, OnInit,OnChanges,ViewChild} from '@angular/core'; import {Test2Component} from "../test2/test2.component" @Component({ selector: 'app-test1', //templateUrl: './test1.component.html', template: ` <div> <input type="text" [(ngModel)]="test1_value1" > <input type="text" [(ngModel)]="test1_value2" > <ng-content></ng-content> <app-test2 [test2_value1]="test1_value1" [test2_value2]="test1_value2"> </app-test2> <div *ngFor="let test of tests" appTest4 class="tests"> {{test}} </div> <input type="button"value="add" (click)="addDiv()"> <input type="button"value="delete"(click)="deleteDiv()"> </div>`, styleUrls: ['./test1.component.css'] }) export class Test1Component implements OnInit, OnChanges{ test1_value1:string; test1_value2:string; tests:any; constructor() { } @ViewChild(Test2Component) viewChild:Test2Component; ngOnInit() { this.test1_value1="1" this.test1_value2="2" this.tests=[1,2,3] } ngOnChanges(){ console.log("onchange"); } addDiv(){ this.tests.push("1212"); } deleteDiv(){ this.tests=[]; } }
import { Directive, OnInit, OnDestroy } from '@angular/core'; @Directive({ selector: '[appTest4]' }) export class Test4Directive implements OnInit, OnDestroy{ constructor() { } ngOnInit() { console.log("test4 directive ngOnInit")} ngOnDestroy() { console.log("test4 directive ngDestroy");} }
因爲生命週期的存在,angular提供了衆多的生命週期的鉤子,讓咱們可以很好的在發生變化的時候進行處理。