跳至主要內容
版本:v8

Ionic 頁面生命週期

本指南涵蓋了使用 Ionic 和 Angular 建置的應用程式中,頁面生命週期的運作方式。

Flowchart illustrating the Ionic page life cycle events and their sequence.

Angular 生命週期事件

Ionic 採用 Angular 提供的生命週期事件。您會發現最常用的兩個 Angular 事件是

事件名稱描述
ngOnInit在元件初始化期間觸發一次。此事件可用於初始化本機成員並呼叫只需要執行一次的服務。
ngOnDestroy在 Angular 銷毀檢視之前觸發。適用於清理工作,例如取消訂閱 observable。

如需更多有關 Angular 元件生命週期事件的資訊,請造訪其元件生命週期文件

注意

使用 ion-navion-router-outlet 的元件不應使用 OnPush 變更偵測策略。這樣做會阻止生命週期掛勾(例如 ngOnInit)觸發。此外,非同步狀態變更可能無法正確呈現。

Ionic 頁面事件

除了 Angular 生命週期事件之外,Ionic Angular 還提供了一些您可以使用的其他事件

事件名稱描述
ionViewWillEnter當路由到的元件即將動畫進入檢視時觸發。
ionViewDidEnter當路由到的元件完成動畫時觸發。
ionViewWillLeave當路由來源的元件即將動畫時觸發。
ionViewDidLeave當路由來源的元件完成動畫時觸發。

這些生命週期僅在由路由器直接對應的元件上呼叫。這表示如果 /pageOne 對應到 PageOneComponent,則 Ionic 生命周期將在 PageOneComponent 上呼叫,但不會在 PageOneComponent 可能呈現的任何子元件上呼叫。

ionViewWillEnterionViewDidEnter 之間的差異在於它們的觸發時間。前者在 ngOnInit 之後但在頁面轉換開始之前立即觸發,後者在轉換結束後立即觸發。

對於 ionViewWillLeaveionViewDidLeaveionViewWillLeave 在開始從目前頁面轉換之前立即呼叫,而 ionViewDidLeave 直到新頁面成功轉換完成後才會呼叫 (在新頁面的 ionViewDidEnter 觸發之後)。

Animated GIF showing Ionic page life cycle events in a console log as a page transition occurs.

Ionic 如何處理頁面的生命週期

Ionic 有自己的路由器出口,稱為 <ion-router-outlet />。此出口擴展了 Angular 的 <router-outlet />,並具有一些額外的功能,可為行動裝置提供更好的體驗。

當應用程式包裝在 <ion-router-outlet /> 中時,Ionic 對導航的處理方式會有些不同。當您導航到新頁面時,Ionic 會將舊頁面保留在現有的 DOM 中,但會將其從檢視畫面中隱藏,並轉換新頁面。我們這樣做的原因有兩個

  1. 我們可以維護舊頁面的狀態 (螢幕上的資料、捲軸位置等)。
  2. 我們可以更順暢地返回頁面,因為它已經存在,不需要重新建立。

只有當頁面「彈出」時,例如透過按下 UI 中的返回按鈕或瀏覽器的返回按鈕時,才會從 DOM 中移除頁面。

由於這種特殊的處理方式,ngOnInitngOnDestroy 方法可能不會在您通常認為它們應該觸發時觸發。

ngOnInit 只會在每次頁面全新建立時觸發,而不會在導航回頁面時觸發。例如,在索引標籤介面中的每個頁面之間導航只會呼叫每個頁面的 ngOnInit 方法一次,但在後續造訪時不會。ngOnDestroy 只會在頁面「彈出」時觸發。

路由守衛

在 Ionic 3 中,有一些額外的生命週期方法可用於控制何時可以進入頁面 (ionViewCanEnter) 和離開頁面 (ionViewCanLeave)。這些可用於保護頁面免受未經授權的使用者存取,並在您不希望使用者離開頁面時將使用者保留在頁面上 (例如在填寫表單時)。

這些方法在 Ionic 4 中已移除,改為使用 Angular 的路由守衛。

路由守衛有助於判斷是否可以對路由採取特定動作。它們是實作特定介面的類別。CanActivateCanDeactivate 介面可用於實作與已移除的事件 ionViewCanEnterionViewCanLeave 相同的邏輯類型。

@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 中清理的頁面清理邏輯。