您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關Angular組件的生命周期有哪些,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
組件聲明周期以及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跟組件的模版,初始化視圖相關的。
父組件初始化或修改子組件的輸入參數時會被調用。
需要先理解js中可變對象 和 不可變對象。
//字符串是不可變的 var greeting = "Hello"; greeting = "Hello World"; //對象是可變的 var user = { name: "Tom" }; user.name = "Jerry";
例子:
child組件有3個屬性,其中2個是輸入屬性。
父組件有一個greeting屬性和一個name屬性是Tom的user對象。
父組件要改變輸入屬性,所以greeting和user.name是雙向綁定。
<div class="parent"> <h3>我是父組件</h3> <div>問候語:<input type="text" [(ngModel)]="greeting"></div> <div> 姓名: <input type="text" [(ngModel)]="user.name"> </div> <app-child [greeting]="greeting" [(user)]="user"> </app-child> </div>
父組件改變兩個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()只有在輸入屬性變化時候被調用。
變更檢測由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.stringify(changes, null, 2)); } ngDoCheck() { 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) {//變化來計數器清0 this.noChangeCount = 0; } else {//沒變化 this.noChangeCount++; console.log("DoCheck:user.name沒變化時ngDoCheck方法已經被調用" + this.noChangeCount + "次") } this.changeDetected = false;//最后不管變沒變標志位復位 } }
頁面加載完成:user.name沒變化時DoCheck方法已經被調用1次。
鼠標點擊,不改變任何值,點擊觸發變更檢測機制,所有組件的DoCheck就會被調用。
修改Tom為Tomb,DoCheck捕捉到Tom變為Tomb。
雖然DoCheck()鉤子可以檢測到user.name什么時候發生變化,但是使用必須小心,ngDoCheck()鉤子被非常頻繁的調用。每次變更檢測周期后發生變化的地方都會調用。
對ngDoCheck()的實現必須非常高效,非常輕量級,否則容易引起性能問題。
上述就是小編為大家分享的Angular組件的生命周期有哪些了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。