Angular 前端

Angular 學習筆記(6) — Router

JamesW 2024/07/01 08:53:14
40

來到了框架的重頭戲:”Router”,靠著URL來達到顯示不同元件的目的,可說是在任何前端使用框架最重要的工具之一。

目標:學習使用Angualr框架。

Router使用

 

設定不同的path,URL會根據route位置對應不同的元件,首頁也可以redirectTo: ’ /首頁路徑’

  • 設定動態路徑(:id),抓取動態參數可讓url放入並顯示不同內容(如商品頁id)

 

  • NgModule中註冊設定的routers:

 

  • 在Html中使用 “router-outlet” 載入設定好的router元件:

 

  • 在不同的url中,即會顯示不同的component內容:

 

  • 透過插入<a routerLink>的方式傳送Url 、並切換component :

 

  • 使用元件參數來動態製作路徑:

 

  • 相對路徑(不帶’/’)會拼接父級路由,絕對路徑(帶’/’)是配置的完整路由,注意app.module.ts裡是否有設定path),才能使用。
  • 在元件裡routerlink裡若非絕對路徑(沒加“/“相對路徑),path字串會追加在URl後放導致錯誤,使用路徑層層級關係,確保跳轉依據從根目錄url開始:

 

  • 透過routerLinkActive=“[class名稱]”,觸發切當前頁面按鈕的外觀樣式:

 

  • router.navigate()來透過用物件導入其他頁

 

  • ActivatedRoute 獲取當前路徑,在constructor中建構使用route:

 

router.navigate()中加入{relativeTo:this.route}, 將導向的路經設定為對應的相對路徑,跟route同一個根目錄。

  • 動態生成新路由route parms,顯示對應的子內容:

 

  • 設定對應的路由參數

 

  • 畫面根據傳遞的url 顯示對應的內容

 

  • 為了能對應變動或新增的URL 產生的畫面,使用subscribe 訂閱監聽URL的路由參數:

 

  • 不會新增資料,雖然已經在routerLink 中的指定路徑,但畫面沒有變化, 需要透過subscribe訂閱,抓取任何URL上的變化,來做畫面上的更新:

 

  • 畫面隨著路由更新:

 

  • 當componet切換時,可以取消訂閱 將paramsSubscription 設定為Subscription參數,作為當前路徑route

 

  • Component切換消失後,將路經參數取消訂閱

 

  • 當輸入一個未知或沒有建立的頁面,透過‘’redirectTo:’’ 來導入錯誤畫面:導向錯誤或未知頁面:

 

  • 若一個route想重複使用(ex:錯誤畫面),只改變節點內容可以在 path 設定data將靜態資料傳入到route裡:

 

 

 

 

  • 在TS載入route data的route data 有兩種方式:

 

  • URL Hashmode,Url 加 “#”

 

QueryParams(?) & Fragment(#)

 

  • 傳遞queryParams 和 fragment 的方式:
  1. Html傳遞a 連結:

 

2. method傳遞:

  • 抓取route的參數,同樣使用subscribe獲取queryParams和 fragment的值:

 

  • 透過subscribe更新params參數變化:

 

  • 透過queryParamsHandling:’preserve’ 在跳轉畫面或元件時, 保留queryParams的參數並能產生對應的畫面:

 

 

this.router.navigate(
      [PageLinkAlias['table-definition']],
      {
        queryParamsHandling: 'merge',
        queryParams: { copyFrom: copiedUid },
      },

    ); 

Child (nested) Routes

 

  • 整理所有Routers 的 module:
  1. 建立app-routing.module.ts ,將所app.module 裡 routing設定移入檔案:

 

2. 引入@NgModule,exports RouterModule 至 APP Module,即可分開使用Router。

  • createUrlTree 允許在 Router Guards 內回傳 UrlTree 物件,來達到轉址功能,一但轉址就會取消既有的瀏覽行為:參考文章

 

//** 登出過後,取消過去所有的瀏覽行為 **/
this.router.createUrlTree(['/auth']);

Guard-Service

守門員Guard被啟動時會觸發這個函式,並按照這個函式的執行結果所回傳的布林值,來判斷使用者可不可以造訪它所看守的路由router。 例如來模擬登入登出裝態。

  • 登入範例:

 

  1. 建立兩層service 作保護(service要送入providers):

 

2. 在auth.service.ts,使用Promise非同步操作,建立完成或失敗後所產生的值,以及控制登入登出的boolean。

Promise 參考: https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Promise

3. 將設定好的service 引入至 auth-guard.service.ts看守路由:

canActivateChild()

  • 編輯提醒範例:

當在編輯尚未完成切換畫面時,可以透過 canDeactivate()來把關去做提醒的功能:

canDeactivate()

Resolver

資料提供者類別可與路由器一起使用,以在導航期間解析資料,透過resolver將動態資料在啟用之前將資料解析。

確保routing載入:id時,若無資料對應的防護措施

  1. 建立resolver service

 

2. 設定解析內容:

3. 解析插入route data:

4. 元件初始化即可載入,在動態資料在啟用之前將資料解析

loadChildren #Lazy Loading

 

/** app-routing.module.ts **/
{
  path: 'recipes',
  loadChildren: () =>
    import('./recipes/recipes.module').then((m) => m.RecipesModule),
 },


/** app.module.ts **/
//不用再次import module 至 app.module
imports: [
    ...
    // RecipesModule, //移除import的module
   ...
  ],
  • 若想預先載入所有module,使用preloadingStrategy

 

/** app-routing.module.ts **/
@NgModule({
 //preloadingStrategy預先載入所有module
  imports: [RouterModule.forRoot(appRoutes,{preloadingStrategy:PreloadAllModules})],
  exports: [RouterModule],
})

結語

JamesW