1. 程式人生 > >Angular4 元件生命週期鉤子

Angular4 元件生命週期鉤子

1.元件生命週期呼叫順序

import { Component, OnInit, OnChanges, DoCheck, AfterContentChecked, AfterContentInit, AfterViewChecked, 
AfterViewInit, SimpleChanges, Input } 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,AfterContentChecked,AfterContentInit,AfterViewChecked,AfterViewInit {
  @Input() name:string;
  logIt(msg:string){
   console.log(`#${logIndex++}  ${msg}`);
  }
 
  ngAfterViewInit(): void {
    this.logIt("name屬性在ngAfterViewInit裡面的值是"+name); 
  }
  ngAfterViewChecked(): void {
    this.logIt("name屬性在ngAfterViewChecked裡面的值是"+name); 
  }
  ngAfterContentInit(): void {
    this.logIt("name屬性在ngAfterContentInit裡面的值是"+name); 
  }
  ngAfterContentChecked(): void {
    this.logIt("name屬性在ngAfterContentChecked裡面的值是"+name); 
  }
  ngDoCheck(): void {
    this.logIt("name屬性在ngDoCheck裡面的值是"+name); 
   }
  ngOnChanges(changes: SimpleChanges): void {
    //changes,輸入屬性的所有變化的值
    let name=changes['name'].currentValue;
    this.logIt("name屬性在ngOnChanges裡面的值是"+name);
  }

  constructor() { 
    this.logIt("name屬性在constructor裡面的值是"+name);
  }

  ngOnInit() {
    this.logIt("name屬性在ngOnInit裡面的值是"+name);
  }

}
執行結果

#1  name屬性在constructor裡面的值是
#2  name屬性在ngOnChanges裡面的值是Tom1,父元件修改或初始化子元件的輸入屬性是被呼叫,一個元件沒有輸入屬性,就永遠不會呼叫,首次呼叫發上在ngOnInit之前,且是多次呼叫
#3  name屬性在ngOnInit裡面的值是,初始化值一定要寫在ngOinit中
#4  name屬性在ngDoCheck裡面的值是
#5  name屬性在ngAfterContentInit裡面的值是
#6  name屬性在ngAfterContentChecked裡面的值是
#7  name屬性在ngAfterViewInit裡面的值是
#8  name屬性在ngAfterViewChecked裡面的值是
#9  name屬性在ngDoCheck裡面的值是
#10  name屬性在ngAfterContentChecked裡面的值是
#11  name屬性在ngAfterViewChecked裡面的值是

2.ngOnChanges鉤子

(1)可變物件:物件

(2)不可變物件:字串

 constructor(){
    //不可變物件:字串
    var greeting="hello";
    greeting="hello world";
    //(1)當字串在記憶體中被創建出來以後,他的值永遠不會被改變
    //(2)記憶體中有兩個字串,且每個字串的值是不可變的
    //(3)對於greeting變數來說他的值是改變的,它的值從第一個字串的地址變成了第二個字串的地址

    //可變物件:物件,當一個物件被建立時,哪怕屬性的值變化了,他還是儲存在固定的記憶體地址
    var user={name:'tom'};
    user.name='jeery';
    //當user物件被建立的時候,user的name屬性指向了被建立的'tom'字串的地址,後來改變了user物件的name屬性指向的'jeery'的地址
    //user物件的記憶體地址並沒有改變
  }
(1)子元件
export class ChildComponent implements OnInit,OnChanges {
  ngOnChanges(changes: SimpleChanges): void {
     console.log(JSON.stringify(changes,null,2));
  }

  constructor() { }
  @Input() greeting:string;
  @Input() user:{name:string};
  message:string="初始化訊息"
  ngOnInit() {
  }

}
模板
<div class="child">
<p>我是子元件</p>
<p> 問候語:{{greeting}}</p>
<p> 姓名:{{user.name}}</p>
<p> 訊息:<input [(ngModel)]="message"/></p>
</div>
(2)父元件傳入並修改子元件的輸入屬性
export class AppComponent {

  greeting:string="Hello";
  user:{name:string}={name:'tom'};
  
  constructor(){
    
  }
}
模板:
<div class="parent">
<p>問候語:<input [(ngModel)]="greeting" /></p>
<p>姓名:<input [(ngModel)]="user.name"/></p>
</div>
<app-child [greeting]="greeting"  [user]="user"></app-child>
(3)

初始化結果

{
  "greeting": {
    "currentValue": "Hello",
    "firstChange": true
  },
  "user": {
    "currentValue": {
      "name": "tom"
    },
    "firstChange": true
  }
}

修改問候語:

{
  "greeting": {
    "previousValue": "Hello",
    "currentValue": "Hello1",
    "firstChange": false
  }
}

修改姓名:沒有反應

修改訊息也沒有反應