angualr4基礎之組件生命週期

組件生命週期

//這個順序是按照執行的先後排列的
constructor:構造器函數,一般用於注入服務
ngOnChanges:檢測到輸入數據變化,首次觸發發生在ngOnInit前。注意對象的屬性發生變化時監聽不到
ngOnInit:組件初始化,通常會設置一些初始值
ngDoCheck:手動觸發更新檢查 
ngAfterContentInit:內容初始化到組件之後
ngAfterContentChecked:內容變更檢測之後
ngAfterViewInit:視圖 初始化之後
ngAfterViewChecked:視圖發生變化檢測之後,這個可以用來保證用戶視圖的及時更新
ngOnDestroy:組件註銷時的清理工作,通常用於移除事件監聽,退訂可觀察對象等
  • ngOnChanges
    • 在父組件初始化或修改子組件的輸入參數時調用。
<!--父組件-->
import { Component } from '@angular/core';
@Component({...})
export class AppComponent {
  greeting:string  = "Hello";//當這個對象變更時,會調用子組件的ngonchange鉤子
  user:{name:string} = {name: "Tom"};
 //當name變更時,不會調用子組件的ngonchange鉤子,因爲他變更的是name屬性而不是user對象。
  constructor(){
}
}
<!--html-->
<div class="parent">
  <h2>我是父組件</h2>
  <div>
    問候語:<input type="text" [(ngModel)]="greeting">//雙向綁定
  </div>
  <div>
    姓名:<input type="text" [(ngModel)]="user.name">//雙向綁定
  </div>
  <app-child [greeting]="greeting" [user]="user"></app-child>//將值傳入子組件,當值改變時會調用子組件的ngonchange鉤子
</div>
  • 變更檢測 ngDoCheck (依賴於zone.js)
    • Default策略
    • OnPush策略
  • 所有的事件都會觸發變更檢測機制,不分原生還是自己寫的
  • 所有帶有check字樣的鉤子都會這樣,只要有一點變動就會調用。除非這個組件被銷燬。(在兩個input框之間切換都回調用)
//跟上邊的代碼一樣,但是當name改變時,也會調用ngDoCheck方法鉤子。
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.stringify(changes, null, 2));
  }
  ngDoCheck(): void {//子組件裏的變更檢測,
    if(this.user.name !== this.oldUsername) {
      this.changeDetected = true;
      console.log("DoCheck:user.name從"+this.oldUsername+"變爲"+this.user.name);
      this.oldUsername = this.user.name;
    }
    if(this.changeDetected) {
      this.noChangeCount = 0;
    }else{
      this.noChangeCount = this.noChangeCount + 1;
      console.log("DoCheck:user.name沒變化時ngDoCheck方法已經被調用"+this.noChangeCount+"次")
    }
    this.changeDetected = false;
  }
}
  • View鉤子
    • 在父組件裏可以通過@ViewChild獲得子組件的引用。調用子組件方法
<!--父組件-->
import {Component, OnInit, ViewChild, AfterViewInit, AfterViewChecked} from "@angular/core";
import {ChildComponent} from "./child/child.component";
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, AfterViewInit,
  @ViewChild("child1")//引入子組件
  child1:ChildComponent;//定義子組件對象
  message:string;
  constructor(){
  }
  ngAfterViewInit(): void {//要想執行這個,必須等子組件全部加載完畢。
    console.log("父組件的視圖初始化完畢");
  //在ngAfterViewInit裏邊不能寫賦值等操作,要想進行這些操作必須寫在settimeout裏邊
    setTimeout(() => {   
      this.message = "Hello";
    },0);
  }
  ngAfterViewChecked(): void {
    console.log("父組件的視圖變更檢測完畢");
  }
  ngOnInit(): void {
    setInterval(() => {
      this.child1.greeting("Tom");//調用子組件裏的方法
    }, 5000);
  }
<!--子組件-->
import {Component, OnInit, AfterViewChecked, AfterViewInit} from '@angular/core';
@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit, AfterViewInit,
  AfterViewChecked {
  ngAfterViewInit(): void {
    console.log("子組件的視圖初始化完畢");
  }
  ngAfterViewChecked(): void {
    console.log("子組件的視圖變更檢測完畢");
  }
  constructor() { }
  ngOnInit() {
  }
  greeting(name:string) {
    console.log("hello "+name);
  }
}
  • ngConent指令
  • ngConent指令用於子組件,可以將父組件的內容投影到子組件
<!--父組件-->
<app-child>
<div class="header">這是頭部,這個div是父組件投影到子組件的</div
<div class="footer">這是底部,這個div是父組件投影到子組件的</div>
</app-child>
<!--子組件-->
<ng-content select=".header"></ng-content>
<ng-content select=".footer"></ng-content>
  • AfterContentInit,
    AfterContentChecked, AfterViewInit
父組件
//在這裏邊可以對屬性內容進行變更
ngAfterContentInit(): void {
    console.log("父組件投影內容初始化完畢");//1
    this.message = "hello world";
  }

  ngAfterContentChecked(): void {
    console.log("父組件投影內容變更檢測完畢");//2
  }

  ngAfterViewInit(): void {
    console.log("父組件視圖內容初始化完畢");//5
  }
  子組件
  ngAfterContentInit(): void {
    console.log("子組件投影內容初始化完畢");//3
    this.message = "hello world";
  }

  ngAfterContentChecked(): void {
    console.log("子組件投影內容變更檢測完畢");//4
  }
  • 銷燬ngOnDestroy
  • 在路由跳轉時會執行的鉤子。銷燬之前的組件。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章