Angular 教程:在單頁(yè)面應(yīng)用中導(dǎo)航

2022-07-04 09:49 更新

在單頁(yè)面應(yīng)用中使用 Angular 路由

本教程將介紹如何構(gòu)建一個(gè)使用多個(gè) Angular 路由的單頁(yè)面應(yīng)用 SPA。

在 SPA(Single Page Application 單頁(yè)面應(yīng)用)中,所有應(yīng)用的所有功能都存在于同一個(gè) HTML 頁(yè)面中。當(dāng)用戶(hù)訪問(wèn)應(yīng)用的各種特性時(shí),瀏覽器只需渲染那些用戶(hù)需要關(guān)心的部分,而不用重新加載頁(yè)面。這種模式可以顯著改善應(yīng)用的用戶(hù)體驗(yàn)。

為了定義用戶(hù)如何在應(yīng)用中導(dǎo)航,你可以使用路由??梢蕴砑右恍┞酚蓙?lái)定義用戶(hù)如何從應(yīng)用的某個(gè)部分導(dǎo)航到另一部分。也可以配置一些路由來(lái)防范意外或未經(jīng)授權(quán)的行為。

要探索本教程的范例應(yīng)用,請(qǐng)參閱現(xiàn)場(chǎng)演練 / 下載范例

目標(biāo)

  • 將范例應(yīng)用的各個(gè)特性組織到一些模塊中。
  • 定義如何導(dǎo)航到組件。
  • 使用參數(shù)把信息傳給組件。
  • 通過(guò)嵌套多個(gè)路由來(lái)構(gòu)造路由體系。
  • 檢查用戶(hù)是否可以訪問(wèn)路由。
  • 控制該應(yīng)用是否可以放棄未保存的更改。
  • 通過(guò)預(yù)先獲取路由數(shù)據(jù)和惰性加載特性模塊來(lái)提高性能。
  • 需要特定的條件來(lái)加載組件。

創(chuàng)建一個(gè)范例應(yīng)用

使用 Angular CLI,創(chuàng)建一個(gè)新的應(yīng)用angular-router-sample。這個(gè)應(yīng)用程序有兩個(gè)組件:crisis-listheroes-list。

  1. 創(chuàng)建一個(gè)新的 Angular 項(xiàng)目 angular-router-sample
  2. ng new angular-router-sample

    當(dāng)系統(tǒng)提示 ?Would you like to add Angular routing?? 時(shí),選擇 ?N?。

    當(dāng)系統(tǒng)提示 ?Which stylesheet format would you like to use?? 時(shí),選擇 ?CSS?。

    一段時(shí)間后,一個(gè)新項(xiàng)目 ?angular-router-sample? 就準(zhǔn)備就緒了。

  3. 在終端上,導(dǎo)航到 ?angular-router-sample? 目錄。
  4. 創(chuàng)建一個(gè)組件 crisis-list。
  5. ng generate component crisis-list
  6. 在你的代碼編輯器中,找到文件 ?crisis-list.component.html? 并用如下 HTML 替換占位符內(nèi)容。
  7. <h3>CRISIS CENTER</h3>
    <p>Get your crisis here</p>
  8. 創(chuàng)建第二個(gè)組件 ?heroes-list?。
  9. ng generate component heroes-list
  10. 在你的代碼編輯器中,找到 ?heroes-list.component.html? 文件,并用如下 HTML 替換占位符內(nèi)容。
  11. <h3>HEROES</h3>
    <p>Get your heroes here</p>
  12. 在你的代碼編輯器中,打開(kāi)文件 ?app.component.html? 并用如下 HTML 替換其內(nèi)容。
  13. <h1>Angular Router Sample</h1>
    <app-crisis-list></app-crisis-list>
    <app-heroes-list></app-heroes-list>
  14. 運(yùn)行 ?ng serve? 來(lái)驗(yàn)證新應(yīng)用是否正常運(yùn)行。
  15. ng serve
  16. 打開(kāi)瀏覽器訪問(wèn) ?http://localhost:4200?。
  17. 你會(huì)看到一個(gè)網(wǎng)頁(yè),它由一個(gè)標(biāo)題和兩個(gè)組件的 HTML 組成。

從 @angular/router 導(dǎo)入 RouterModule

路由允許你根據(jù) URL 路徑顯示應(yīng)用的特定視圖。要把這個(gè)功能添加到你的范例應(yīng)用中,你需要更新 ?app.module.ts? 文件以使用模塊 ?RouterModule?。你可以從 ?@angular/router? 導(dǎo)入該模塊。

  1. 在代碼編輯器中,打開(kāi) ?app.module.ts? 文件。
  2. 添加如下 ?import ?語(yǔ)句。
  3. import { RouterModule } from '@angular/router';

定義你的各個(gè)路由

在本節(jié)中,你將定義兩個(gè)路由:

  • 路由 ?/crisis-center? 用來(lái)打開(kāi) ?crisis-center? 組件。
  • 路由 ?/heroes-list? 用來(lái)打開(kāi) ?heroes-list? 組件。

路由定義是一個(gè) JavaScript 對(duì)象。每個(gè)路由通常都有兩個(gè)屬性。第一個(gè)屬性 ?path ?是一個(gè)字符串,它指定路由的 URL 路徑。第二個(gè)屬性 ?component ?是組件類(lèi),它指定應(yīng)用要為該路由顯示哪個(gè)組件。

  1. 在代碼編輯器中,打開(kāi) ?app.module.ts? 文件。
  2. 找到 ?@NgModule()? 部分。
  3. 用如下代碼替換這部分的 ?imports ?數(shù)組。
  4. imports: [
      BrowserModule,
      RouterModule.forRoot([
        {path: 'crisis-list', component: CrisisListComponent},
        {path: 'heroes-list', component: HeroesListComponent},
      ]),
    ],

這段代碼把 ?RouterModule ?添加到了 ?imports ?數(shù)組中。接下來(lái),該代碼使用 ?RouterModule ?的 ?forRoot()? 方法來(lái)定義你的兩個(gè)路由。該方法接受一個(gè) JavaScript 對(duì)象數(shù)組,每個(gè)對(duì)象定義一個(gè)路由的屬性。?forRoot()? 方法確保你的應(yīng)用只會(huì)實(shí)例化一個(gè) ?RouterModule?。

更新你的組件以添加 router-outlet

此刻,你已經(jīng)為應(yīng)用定義了兩個(gè)路由。但是,你的應(yīng)用仍然在你的 ?app.component.html? 模板中硬編碼著 ?crisis-list? 和 ?heroes-list? 組件。為了讓你的路由正常工作,需要更新模板,以便根據(jù) URL 路徑動(dòng)態(tài)加載一個(gè)組件。

要實(shí)現(xiàn)這個(gè)功能,你就可以把 ?router-outlet? 指令添加到模板文件中。

  1. 在代碼編輯器中,打開(kāi) ?app.component.html? 文件。
  2. 刪除下面這幾行。
  3. <app-crisis-list></app-crisis-list>
    <app-heroes-list></app-heroes-list>
  4. 添加 ?router-outlet? 指令。
  5. <router-outlet></router-outlet>

在瀏覽器中查看更新后的應(yīng)用。你應(yīng)該只看到應(yīng)用標(biāo)題。要查看 ?crisis-list? 組件,就要把 ?crisis-list? 添加到瀏覽器地址欄的路徑末尾。比如:

http://localhost:4200/crisis-list

注意,?crisis-list? 組件會(huì)顯示出來(lái)。Angular 正在使用你定義的路由來(lái)動(dòng)態(tài)加載組件。你可以用同樣的方法加載 ?heroes-list? 組件:

http://localhost:4200/heroes-list

用 UI 元素控制導(dǎo)航

目前,你的應(yīng)用支持兩種路由。但是目前使用這些路由的唯一方法是讓用戶(hù)在瀏覽器的地址欄中手動(dòng)輸入路徑。在本節(jié)中,你要添加兩個(gè)鏈接,用戶(hù)可以單擊它們?cè)?nbsp;?heroes-list? 和 ?crisis-list? 組件之間導(dǎo)航。你還會(huì)添加一些 CSS 樣式。雖然這些樣式不是必需的,但它們可以讓你更容易的識(shí)別出當(dāng)前顯示的組件的鏈接。你將在下一節(jié)中添加此功能。

  1. 打開(kāi) ?app.component.html? 文件,在標(biāo)題下方添加以下 HTML。
  2. <nav>
      <a class="button" routerLink="/crisis-list">Crisis Center</a> |
      <a class="button" routerLink="/heroes-list">Heroes</a>
    </nav>

    這個(gè) HTML 使用了 Angular 指令 ?routerLink?。該指令將你定義的路由連接到模板文件中。

  3. 打開(kāi) ?app.component.css? 文件并添加如下樣式。
  4. .button {
        box-shadow: inset 0 1px 0 0 #ffffff;
        background: #ffffff linear-gradient(to bottom, #ffffff 5%, #f6f6f6 100%);
        border-radius: 6px;
        border: 1px solid #dcdcdc;
        display: inline-block;
        cursor: pointer;
        color: #666666;
        font-family: Arial, sans-serif;
        font-size: 15px;
        font-weight: bold;
        padding: 6px 24px;
        text-decoration: none;
        text-shadow: 0 1px 0 #ffffff;
        outline: 0;
    }
    .activebutton {
        box-shadow: inset 0 1px 0 0 #dcecfb;
        background: #bddbfa linear-gradient(to bottom, #bddbfa 5%, #80b5ea 100%);
        border-radius: 6px;
        border: 1px solid #84bbf3;
        display: inline-block;
        cursor: pointer;
        color: #ffffff;
        font-family: Arial, sans-serif;
        font-size: 15px;
        font-weight: bold;
        padding: 6px 24px;
        text-decoration: none;
        text-shadow: 0 1px 0 #528ecc;
        outline: 0;
    }

如果你在瀏覽器中查看應(yīng)用,你會(huì)看到這兩個(gè)鏈接。單擊某個(gè)鏈接時(shí),會(huì)出現(xiàn)相應(yīng)的組件。

標(biāo)出活動(dòng)路由

雖然用戶(hù)可以使用上一節(jié)中添加的鏈接來(lái)瀏覽你的應(yīng)用,但他們并沒(méi)有簡(jiǎn)單的方法來(lái)確定活動(dòng)路由是什么??梢杂?nbsp;Angular 的 ?routerLinkActive ?指令添加這個(gè)功能。

  1. 在代碼編輯器中,打開(kāi) ?app.component.html? 文件。
  2. 更新 a 標(biāo)簽以包含 ?routerLinkActive ?指令。
  3. <nav>
      <a class="button"
         routerLink="/crisis-list"
         routerLinkActive="activebutton"
         ariaCurrentWhenActive="page">
        Crisis Center
      </a> |
      <a class="button"
         routerLink="/heroes-list"
         routerLinkActive="activebutton"
         ariaCurrentWhenActive="page">
        Heroes
      </a>
    </nav>

再次查看你的申請(qǐng)表。單擊其中一個(gè)按鈕時(shí),該按鈕的樣式會(huì)自動(dòng)更新,并為該用戶(hù)標(biāo)出該活動(dòng)組件。通過(guò)添加 ?routerLinkActive ?指令,可以通知你的應(yīng)用把一個(gè)特定的 CSS 類(lèi)應(yīng)用到當(dāng)前的活動(dòng)路由中。在本教程中,這個(gè) CSS 類(lèi)是 ?activebutton?,但你可以使用任何想要的類(lèi)。

請(qǐng)注意,我們還為 ?routerLinkActive ?的 ?ariaCurrentWhenActive ?指定了一個(gè)值。這可確保視障用戶(hù)(他們可能無(wú)法感知正在應(yīng)用的不同樣式)也可以識(shí)別活動(dòng)按鈕。

添加一個(gè)重定向

在本教程的這一步中,你將添加一個(gè)重定向路由來(lái)把用戶(hù)導(dǎo)向 ?/heroes-list? 組件。

  1. 在代碼編輯器中,打開(kāi) ?app.module.ts? 文件。
  2. 在 ?imports ?數(shù)組中,按如下所示更新 ?RouterModule ?部分。
imports: [
  BrowserModule,
  RouterModule.forRoot([
    {path: 'crisis-list', component: CrisisListComponent},
    {path: 'heroes-list', component: HeroesListComponent},
    {path: '', redirectTo: '/heroes-list', pathMatch: 'full'},
  ]),
],

注意這個(gè)新路由使用一個(gè)空字符串作為它的路徑。另外,它還把 ?component ?屬性替換成了這兩個(gè)新屬性:

屬性

詳情

redirectTo

這個(gè)屬性指示 Angular 從空路徑重定向到 heroes-list 路徑。

pathMatch

這個(gè)屬性指示 Angular 要如何匹配 URL。對(duì)于本教程,你應(yīng)該把這個(gè)屬性設(shè)置為 full。當(dāng)路徑為空字符串時(shí),建議使用此策略。

現(xiàn)在,當(dāng)你打開(kāi)應(yīng)用時(shí),它會(huì)默認(rèn)顯示 ?heroes-list? 組件。

添加 404 頁(yè)面

用戶(hù)可以嘗試訪問(wèn)你尚未定義的路由。為了解決這個(gè)問(wèn)題,最佳做法是顯示一個(gè) 404 頁(yè)面。在本節(jié)中,你將創(chuàng)建一個(gè) 404 頁(yè)面,并更新路由配置,以便為任何未指定的路由顯示該頁(yè)面。

  1. 在終端上,創(chuàng)建一個(gè)新的組件 ?PageNotFound?。
  2. ng generate component page-not-found
  3. 在代碼編輯器中,打開(kāi) ?page-not-found.component.html? 文件并用下面的 HTML 替換它的內(nèi)容。
  4. <h2>Page Not Found</h2>
    <p>We couldn't find that page! Not even with x-ray vision.</p>
  5. 打開(kāi) ?app.module.ts? 文件。在其 ?imports ?數(shù)組中,按如下所示更新 ?RouterModule ?部分的內(nèi)容。
  6. imports: [
      BrowserModule,
      RouterModule.forRoot([
        {path: 'crisis-list', component: CrisisListComponent},
        {path: 'heroes-list', component: HeroesListComponent},
        {path: '', redirectTo: '/heroes-list', pathMatch: 'full'},
        {path: '**', component: PageNotFoundComponent}
      ]),
    ],

    新路由使用路徑 ?**?。這個(gè)路徑是 Angular 表示通配符路由的方式。任何與你配置中的路由都不匹配的路由都會(huì)使用這個(gè)路由。

    請(qǐng)注意,通配符路由要放在數(shù)組的末尾。路由的順序很重要,因?yàn)?nbsp;Angular 會(huì)按順序應(yīng)用路由并使用所找到的第一個(gè)匹配項(xiàng)。

嘗試導(dǎo)航到應(yīng)用中不存在的路由,比如 ?http://localhost:4200/powers?。此路由與 ?app.module.ts? 文件中定義的所有內(nèi)容都不匹配。但是,由于你定義了一個(gè)通配符路由,該應(yīng)用會(huì)自動(dòng)顯示你的 ?PageNotFound ?組件。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)