Ionic 頁面生命週期
本指南涵蓋了使用 Ionic 和 Angular 建置的應用程式中,頁面生命週期的運作方式。
Angular 生命週期事件
Ionic 採用 Angular 提供的生命週期事件。您會發現最常用的兩個 Angular 事件是
事件名稱 | 描述 |
---|---|
ngOnInit | 在元件初始化期間觸發一次。此事件可用於初始化本機成員並呼叫只需要執行一次的服務。 |
ngOnDestroy | 在 Angular 銷毀檢視之前觸發。適用於清理工作,例如取消訂閱 observable。 |
如需更多有關 Angular 元件生命週期事件的資訊,請造訪其元件生命週期文件。
使用 ion-nav
或 ion-router-outlet
的元件不應使用 OnPush
變更偵測策略。這樣做會阻止生命週期掛勾(例如 ngOnInit
)觸發。此外,非同步狀態變更可能無法正確呈現。
Ionic 頁面事件
除了 Angular 生命週期事件之外,Ionic Angular 還提供了一些您可以使用的其他事件
事件名稱 | 描述 |
---|---|
ionViewWillEnter | 當路由到的元件即將動畫進入檢視時觸發。 |
ionViewDidEnter | 當路由到的元件完成動畫時觸發。 |
ionViewWillLeave | 當路由來源的元件即將動畫時觸發。 |
ionViewDidLeave | 當路由來源的元件完成動畫時觸發。 |
這些生命週期僅在由路由器直接對應的元件上呼叫。這表示如果 /pageOne
對應到 PageOneComponent
,則 Ionic 生命周期將在 PageOneComponent
上呼叫,但不會在 PageOneComponent
可能呈現的任何子元件上呼叫。
ionViewWillEnter
和 ionViewDidEnter
之間的差異在於它們的觸發時間。前者在 ngOnInit
之後但在頁面轉換開始之前立即觸發,後者在轉換結束後立即觸發。
對於 ionViewWillLeave
和 ionViewDidLeave
,ionViewWillLeave
在開始從目前頁面轉換之前立即呼叫,而 ionViewDidLeave
直到新頁面成功轉換完成後才會呼叫 (在新頁面的 ionViewDidEnter
觸發之後)。
Ionic 如何處理頁面的生命週期
Ionic 有自己的路由器出口,稱為 <ion-router-outlet />
。此出口擴展了 Angular 的 <router-outlet />
,並具有一些額外的功能,可為行動裝置提供更好的體驗。
當應用程式包裝在 <ion-router-outlet />
中時,Ionic 對導航的處理方式會有些不同。當您導航到新頁面時,Ionic 會將舊頁面保留在現有的 DOM 中,但會將其從檢視畫面中隱藏,並轉換新頁面。我們這樣做的原因有兩個
- 我們可以維護舊頁面的狀態 (螢幕上的資料、捲軸位置等)。
- 我們可以更順暢地返回頁面,因為它已經存在,不需要重新建立。
只有當頁面「彈出」時,例如透過按下 UI 中的返回按鈕或瀏覽器的返回按鈕時,才會從 DOM 中移除頁面。
由於這種特殊的處理方式,ngOnInit
和 ngOnDestroy
方法可能不會在您通常認為它們應該觸發時觸發。
ngOnInit
只會在每次頁面全新建立時觸發,而不會在導航回頁面時觸發。例如,在索引標籤介面中的每個頁面之間導航只會呼叫每個頁面的 ngOnInit
方法一次,但在後續造訪時不會。ngOnDestroy
只會在頁面「彈出」時觸發。
路由守衛
在 Ionic 3 中,有一些額外的生命週期方法可用於控制何時可以進入頁面 (ionViewCanEnter
) 和離開頁面 (ionViewCanLeave
)。這些可用於保護頁面免受未經授權的使用者存取,並在您不希望使用者離開頁面時將使用者保留在頁面上 (例如在填寫表單時)。
這些方法在 Ionic 4 中已移除,改為使用 Angular 的路由守衛。
路由守衛有助於判斷是否可以對路由採取特定動作。它們是實作特定介面的類別。CanActivate
和 CanDeactivate
介面可用於實作與已移除的事件 ionViewCanEnter
和 ionViewCanLeave
相同的邏輯類型。
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.authService.isAuthenticated();
}
}
若要使用此守衛,請將其新增至路由定義中的適當參數
{ path: 'settings', canActivate: [AuthGuard], loadChildren: '...', }
如需更多有關如何使用路由守衛的資訊,請前往 Angular 的路由器文件。
每個生命週期方法的指南
以下是一些有關每個生命週期事件用例的提示。
ngOnInit
- 初始化您的元件並從不需要在每次後續造訪時刷新的服務載入資料。ionViewWillEnter
- 由於每次導航至檢視畫面時都會呼叫ionViewWillEnter
(無論是否已初始化),因此它是從服務載入資料的好方法。但是,如果您的資料在動畫期間傳回,它可能會開始進行大量的 DOM 操作,這可能會導致一些不穩定的動畫。ionViewDidEnter
- 如果您在使用ionViewWillEnter
載入資料時發現效能問題,則可以在ionViewDidEnter
中進行資料呼叫。此事件只有在使用者可看見頁面後才會觸發,因此您可能需要使用載入指示器或骨架螢幕,這樣內容才不會在轉換完成後不自然地閃爍。ionViewWillLeave
- 可用於清理,例如取消訂閱 observables。由於當您從目前頁面導航離開時,ngOnDestroy
可能不會觸發,如果您不希望螢幕不在視野中時它仍然處於活動狀態,請將您的清理程式碼放在這裡。ionViewDidLeave
- 當此事件觸發時,您就知道新頁面已完全轉換進入,因此您通常在視圖可見時不會執行的任何邏輯都可以放在這裡。ngOnDestroy
- 您不想在ionViewWillLeave
中清理的頁面清理邏輯。