詳解Angular組件之生命周期(二)
一、view鉤子
view鉤子有2個(gè),ngAfterViewInit和ngAfterViewChecked鉤子。
1、實(shí)現(xiàn)ngAfterViewInit和ngAfterViewChecked鉤子時(shí)注意事項(xiàng)
以父組件調(diào)用子組件方法中例子為基礎(chǔ),在父組件中實(shí)現(xiàn)ngAfterViewInit和ngAfterViewChecked鉤子。
這兩個(gè)鉤子是在組件的模版所有內(nèi)容組裝完成后,組件模版已經(jīng)呈現(xiàn)給用戶看了,之后這兩個(gè)鉤子方法會(huì)被調(diào)用。
@ViewChild('child1') child1:Child1Component; //父組件中獲得子組件的引用 ngOnInit(){ this.child1.greeting("Tom"); } ngAfterViewInit(){ console.log("父組件的視圖初始化完畢"); } ngAfterViewChecked(){ console.log("父組件的視圖變更檢測完畢"); }
在子組件中也實(shí)現(xiàn)這兩個(gè)鉤子
export class Child1Component implements OnInit,AfterViewInit,AfterViewChecked{ constructor() { } ngOnInit() { } greeting(name: string) { console.log("hello" + name); } ngAfterViewInit(){ console.log("子組件的視圖初始化完畢"); } ngAfterViewChecked(){ console.log("子組件的視圖變更檢測完畢"); } }
在父組件的ngOnInit中不直接調(diào)用子組件的greeting()方法,而是通過一個(gè)定時(shí)器每隔5s去調(diào)用一次。
ngOnInit(){ setInterval(()=>{ this.child1.greeting("Tom"); },5000); }
總結(jié):
1、Init先調(diào)用,checked后調(diào)用
看1中,首先子組件視圖初始化完畢,然后子組件視圖變更檢測完畢。
2、子組件先于父組件被組裝好
看2中,因?yàn)楦附M件中聲明了2個(gè)子組件,所以看到有2個(gè)子組件 初始化的動(dòng)作。1號子組件初始化完畢,變更檢測完畢,2號子組件初始化完畢,變更檢測完畢后,父組件的初始化完畢才會(huì)被調(diào)用,然后父組件的變更檢測完畢才會(huì)被調(diào)用。
3、ngAfterViewInit只會(huì)在初始化完畢被調(diào)用一次。
4、定時(shí)器觸發(fā)方法后,兩個(gè)子組件的變更檢測會(huì)被調(diào)用,父組件的變更檢測也會(huì)被調(diào)用。
視圖沒有發(fā)生任何改變,變更檢測也會(huì)被調(diào)用,實(shí)現(xiàn)來ngAfterViewChecked()鉤子的方法都會(huì)被調(diào)用。
所以ngAfterViewChecked()鉤子一定要寫的精簡以免出現(xiàn)性能問題。
2、在一個(gè)變更檢測周期中禁止一個(gè)視圖被組裝好之后再去更新視圖
例子:
父組件
有一個(gè)message初始化為abc.顯示到模版上。
message:string='abc';
在父組件的ngAfterViewInit中更改message值。
ngAfterViewInit(){ console.log("父組件的視圖初始化完畢"); this.message="def"; }
會(huì)報(bào)錯(cuò)。ngAfterViewInit()和ngAfterViewChecked()都是在視圖組裝完成后觸發(fā)的,所以在這兩個(gè)鉤子中更新組件中被綁定的屬性,觸發(fā)組件視圖的變化,Angular就會(huì)拋出異常。
解決辦法:
把代碼放在另一個(gè)時(shí)間循環(huán)里面。
ngAfterViewInit(){ console.log("父組件的視圖初始化完畢"); setTimeout(()=>{ this.message="def"; },0); }
二、content鉤子
包括2個(gè)與投影相關(guān)的鉤子,ngAfterContentInit()和ngAfterContentChecked()鉤子。
ngAfterContentInit,ngAfterContentChecked和ngAfterViewInit,ngAfterViewChecked類似。
ngAfterViewInit,ngAfteViewChecked是在整個(gè)組件的視圖全部組裝完成后調(diào)用的。
ngAfterContentInit,ngAfterContentChecked是在被投影進(jìn)來的內(nèi)容組裝完成后調(diào)用的。
1、Content鉤子的調(diào)用順序例子
父組件中實(shí)現(xiàn)ngAfterContentInit,ngAfterContentChecked和ngAfterContentInit()
export class AppComponent implements OnInit, AfterViewInit, AfterContentInit,AfterContentChecked{ ngAfterViewInit(){ console.log("父組件的視圖初始化完畢"); } ngAfterContentInit(){ console.log("父組件投影內(nèi)容初始化完畢"); } ngAfterContentChecked(){ console.log("父組件投影內(nèi)容變更檢測完畢"); }
子組件中也實(shí)現(xiàn)這3個(gè)接口
export class Child2Component implements OnInit,AfterViewChecked,AfterContentInit,AfterContentChecked{ constructor() { } ngOnInit() { } ngAfterViewInit(){ console.log("子組件的視圖初始化完畢"); } ngAfterContentInit(){ console.log("子組件投影內(nèi)容初始化完畢"); } ngAfterContentChecked(){ console.log("子組件投影內(nèi)容變更檢測完畢"); } }
組裝視圖時(shí),先組裝投影進(jìn)來的內(nèi)容,然后組裝子組件中視圖的內(nèi)容,再加上父組件本身的內(nèi)容,然后才是父組件視圖初始化完畢。
2、Content鉤子中可以修改模版內(nèi)容
view鉤子里不能修改模版內(nèi)容,因?yàn)槟0鎯?nèi)容組裝完畢后不能再修改里面內(nèi)容。但是Content鉤子里可以。
因?yàn)镃ontent鉤子調(diào)用時(shí)整個(gè)視圖還沒有組裝完畢,只是投影進(jìn)來的內(nèi)容被組裝完畢了。
父組件中在ngAfterContentInit鉤子里修改message信息不會(huì)報(bào)錯(cuò)。
export class AppComponent implements OnInit, AfterViewInit, AfterContentInit,AfterContentChecked{ message:string='abc'; ngAfterViewInit(){ console.log("父組件的視圖初始化完畢"); } ngAfterContentInit(){ console.log("父組件投影內(nèi)容初始化完畢"); this.message='def'; } ngAfterContentChecked(){ console.log("父組件投影內(nèi)容變更檢測完畢"); } ngOnInit(){ }
三、總結(jié)
上面四個(gè)方法在屬性初始化階段:構(gòu)造函數(shù)是初始化對象,ngOnChanges是初始化輸入屬性,ngOnInit是初始化除了輸入屬性以外其它的所有屬性,ngDoCheck是做一次變更檢查。
這四個(gè)方法執(zhí)行完整個(gè)組件所有屬性都被賦予了應(yīng)該被賦的值。
組件開始渲染它的視圖,首先渲染投影進(jìn)來的內(nèi)容,投影進(jìn)來的內(nèi)容渲染完調(diào)用ngAfterContentInit和ngAfterContentChecked鉤子方法。
如果有子組件會(huì)調(diào)子組件創(chuàng)建的過程,子組件創(chuàng)建完或者沒有子組件,整個(gè)組件的視圖都初始化完畢了以后,會(huì)調(diào)ngAfterViewInit和ngAfterViewChecked鉤子方法。
至此,整個(gè)組件初始化完畢,組件會(huì)呈現(xiàn)給用戶交互。
用戶交互觸發(fā)Angular的變更檢測機(jī)制,檢測到發(fā)生了變更,在當(dāng)前組件樹上所有活動(dòng)組件上被實(shí)現(xiàn)的帶有check的鉤子方法都會(huì)被調(diào)用,用來檢查當(dāng)前組件的變化,如果變化導(dǎo)致某個(gè)組件的輸入屬性也改變了,那個(gè)組件的ngOnChanges也會(huì)被調(diào)用。
組件在路由地址變化從而被銷毀的時(shí)候會(huì)調(diào)ngOnDestory()。
在ngOnDestory中銷毀一些引用的資源,比如反訂閱一個(gè)流,清除定時(shí)器之類的。
以上就是詳解Angular組件之生命周期(二)的詳細(xì)內(nèi)容,更多關(guān)于Angular的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
AngularJS轉(zhuǎn)換響應(yīng)內(nèi)容
這篇文章主要介紹了AngularJS轉(zhuǎn)換響應(yīng)內(nèi)容 的相關(guān)資料,需要的朋友可以參考下2016-01-01Angular.JS中指令ng-if、ng-show/ng-hide和ng-switch的使用教程
在Angular的原生指令中有這幾個(gè)指令用來控制元素的展示與否,ng-show/ng-hide/ng-if和ng-switch。在angular性能優(yōu)化中,我們也常常會(huì)用到它。這篇文章主要給大家介紹了在Angular.JS中指令ng-if、ng-show/ng-hide和ng-switch的使用教程,需要的朋友可以參考。2017-05-05angularjs學(xué)習(xí)筆記之完整的項(xiàng)目結(jié)構(gòu)
這篇文章主要介紹了angularjs學(xué)習(xí)筆記之完整的項(xiàng)目結(jié)構(gòu)的相關(guān)資料,需要的朋友可以參考下2015-09-09angularJS實(shí)現(xiàn)表格部分列展開縮起示例代碼
這篇文章主要介紹了angularJS實(shí)現(xiàn)表格部分列展開縮起示例代碼,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09Angular懶加載模塊與Combined?Injector原理全面解析
這篇文章主要為大家介紹了Angular懶加載模塊與Combined?Injector原理全面解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10詳解Angular Karma測試的持續(xù)集成實(shí)踐
這篇文章主要介紹了詳解Angular Karma測試的持續(xù)集成實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11angular6根據(jù)environments配置文件更改開發(fā)所需要的環(huán)境的方法
這篇文章主要介紹了angular6根據(jù)environments配置文件更改開發(fā)所需要的環(huán)境的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-03-03AngularJS中ng-options實(shí)現(xiàn)下拉列表的數(shù)據(jù)綁定方法
今天小編就為大家分享一篇AngularJS中ng-options實(shí)現(xiàn)下拉列表的數(shù)據(jù)綁定方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08