填寫這份《一分鐘調查》,幫我們(開發組)做得更好!去填寫Home

路由

Adding navigation

第一部分結束時,這個線上商店應用會有一個基本的商品名錄。該應用還沒有任何可變的狀態或導航。它只有一個 URL,該 URL 總是會顯示“我的商店”頁面,其中是商品列表及其描述。

At the end of part 1, the online store application has a basic product catalog. The app doesn't have any variable states or navigation. There is one URL, and that URL always displays the "My Store" page with a list of products and their descriptions.

本指南會告訴你如何使用 Angular 路由來讓使用者進行應用內導航。在單頁面應用中,你不會重新載入新頁面,而是根據使用者所在的位置,向他顯示不同的元件和資料。

This guide shows you how to use Angular routing to give the user in-app navigation. In a single-page app, instead of loading new pages, you show different components and data to the user based on where the user is in the application.

Angular 路由器能讓你在不同的檢視中顯示產品的詳情,每個產品都有自己的 URL。當用戶執行應用任務時,路由器可以從一個檢視導航到另一個檢視(但在同一個頁面)。比如:

The router lets you display full product details in separate views, each with its own URL. Routing enables navigation from one view to the next (within the same page) as users perform tasks such as the following:

  • 在位址列中輸入一個 URL,導航到相應的頁面。

    Entering a URL in the address bar to navigate to a corresponding view.

  • 點選頁面上的連結,導航到新頁面。

    Clicking links on the page to navigate to a new view.

  • 點選瀏覽器的後退和前進按鈕,在瀏覽器的歷史中前後導航。

    Clicking the browser's back and forward buttons to navigate backward and forward through the browser history.

註冊路由

Registering a route

該應用已經設定為使用 Angular Router,並透過路由導航到之前修改過的商品列表元件。本節會向你展示如何定義一個可以顯示單個商品詳情的路由。

The app is already set up to use the Angular Router and to use routing to navigate to the product list component you modified earlier. This section shows you how to define a route to show individual product details.

  1. 為商品詳情產生一個新元件。把元件命名為 product-details

    Generate a new component for product details. Give the component the name product-details.

    提示:在檔案列表框中,右鍵單擊 app 資料夾,選擇 Angular GeneratorComponent

    Reminder: In the file list, right-click the app folder, choose Angular Generator and Component.

  2. app.module.ts 中,新增一個商品詳情路由,該路由的 pathproducts/:productIdcomponentProductDetailsComponent

    In app.module.ts, add a route for product details, with a path of products/:productId and ProductDetailsComponent for the component.

    @NgModule({ imports: [ BrowserModule, ReactiveFormsModule, RouterModule.forRoot([ { path: '', component: ProductListComponent }, { path: 'products/:productId', component: ProductDetailsComponent }, ]) ],
    src/app/app.module.ts
          
          @NgModule({
      imports: [
        BrowserModule,
        ReactiveFormsModule,
        RouterModule.forRoot([
          { path: '', component: ProductListComponent },
          { path: 'products/:productId', component: ProductDetailsComponent },
        ])
      ],
        

    路由會將一個或多個 URL 路徑與一個元件關聯起來。

    A route associates one or more URL paths with a component.

  3. 該指令配置元件的範本,以定義使用者如何導航到路由或 URL。當用戶點選商品名稱時,應用就會顯示那個商品的詳情。

    The directive configures the component template to define how the user navigates to the route or URL. When the user clicks a product name, the app displays the details for that product.

    1. 開啟 product-list.component.html

      Open product-list.component.html.

    2. 修改 *ngFor 指令,在遍歷列表的過程中把 products 陣列中的每個索引賦值給 productId 變數。

      Update the *ngFor directive to assign each index in the products array to the productId variable when iterating over the list.

    3. 修改商品名稱的連結,使其包含 routerLink

      Modify the product name anchor to include a routerLink.

    <div *ngFor="let product of products; index as productId"> <h3> <a [title]="product.name + ' details'" [routerLink]="['/products', productId]"> {{ product.name }} </a> </h3> <!-- . . . --> </div>
    src/app/product-list/product-list.component.html
          
          <div *ngFor="let product of products; index as productId">
    
      <h3>
        <a [title]="product.name + ' details'" [routerLink]="['/products', productId]">
          {{ product.name }}
        </a>
      </h3>
    <!-- . . . -->
    </div>
        

    RouterLink 指令讓路由器控制了一個連結元素。在這種情況下,路由或 URL 包含一個固定的區段( /products ),但其最後一個區段是變數,要插入當前商品的 id 屬性。例如,id 為 1 的商品的 URL 類似於 https://getting-started-myfork.stackblitz.io/products/1

    The RouterLink directive gives the router control over the anchor element. In this case, the route, or URL, contains one fixed segment, /products, while the final segment is variable, inserting the id property of the current product. For example, the URL for a product with an id of 1 will be similar to https://getting-started-myfork.stackblitz.io/products/1.

    1. 透過單擊商品名稱來測試路由器。該應用會顯示商品詳情元件,該元件目前始終顯示 “product-details works!”

      Test the router by clicking a product name. The app displays the product details component, which currently always says "product-details works!"

      注意預覽視窗中的 URL 變化了。它的最後一段是 products/#,這裡的 # 代表你點選的那個路由的編號。

      Notice that the URL in the preview window changes. The final segment is products/# where # is the number of the route you clicked.

使用路由資訊

Using route information

商品詳情元件負責處理每個商品的顯示。Angular 的路由器會根據瀏覽器的 URL 和你定義的這些路由來決定如何顯示元件。本節會告訴你如何透過 Angular 的路由器來組合使用 products 資料和路由資訊,以顯示每個商品的詳情。

The product details component handles the display of each product. The Angular Router displays components based on the browser's URL and your defined routes. This section shows you how to use the Angular Router to combine the products data and route information to display the specific details for each product.

  1. 開啟 product-details.component.ts 檔案

    Open product-details.component.ts

  2. 改用外部檔案中的商品資料。

    Arrange to use product data from an external file.

    1. @angular/router 套件匯入 ActivatedRoute,從 ../products 檔案匯入 products 陣列。

      Import ActivatedRoute from the @angular/router package, and the products array from ../products.

      import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { products } from '../products';
      src/app/product-details/product-details.component.ts
            
            import { Component, OnInit } from '@angular/core';
      import { ActivatedRoute } from '@angular/router';
      
      import { products } from '../products';
          
    2. 定義 product 屬性,並將 ActivatedRoute 作為引數新增到建構函式的括號中,以便把它注入到建構函式中。

      Define the product property and inject the ActivatedRoute into the constructor by adding it as an argument within the constructor's parentheses.

      export class ProductDetailsComponent implements OnInit { product; constructor( private route: ActivatedRoute, ) { } }
      src/app/product-details/product-details.component.ts
            
            export class ProductDetailsComponent implements OnInit {
        product;
      
        constructor(
          private route: ActivatedRoute,
        ) { }
      
      }
          

      ActivatedRoute 專門用於由 Angular 路由器載入的每個路由元件。它包含關於該路由,路由引數以及與該路由關聯的其它資料的資訊。

      The ActivatedRoute is specific to each routed component that the Angular Router loads. It contains information about the route, its parameters, and additional data associated with the route.

      透過注入 ActivatedRoute,你把該元件配置成了使用服務的。《快速上手》課程中的這部分只是簡略使用了該語法,在管理資料部分深入講解了服務的更多細節。

      By injecting the ActivatedRoute, you are configuring the component to use a service. The Managing Data page covers services in more detail.

  3. ngOnInit() 方法中訂閱了路由引數,並且根據 productId 獲取了該產品。

    In the ngOnInit() method, subscribe to route parameters and fetch the product based on the productId.

    ngOnInit() { this.route.paramMap.subscribe(params => { this.product = products[+params.get('productId')]; }); }
    src/app/product-details/product-details.component.ts
          
          ngOnInit() {
      this.route.paramMap.subscribe(params => {
        this.product = products[+params.get('productId')];
      });
    }
        

    這個路由引數對應於你在路由中定義的路徑變數。與該路由匹配的 URL 提供了 productId。Angular 使用這個 productId 來顯示每個單獨商品的詳細資訊。

    The route parameters correspond to the path variables you define in the route. The URL that matches the route provides the productId. Angular uses the productId to display the details for each unique product.

  4. 修改範本,在 *ngIf 中顯示商品詳情。

    Update the template to display product details information inside an *ngIf.

    <h2>Product Details</h2> <div *ngIf="product"> <h3>{{ product.name }}</h3> <h4>{{ product.price | currency }}</h4> <p>{{ product.description }}</p> </div>
    src/app/product-details/product-details.component.html
          
          <h2>Product Details</h2>
    
    <div *ngIf="product">
      <h3>{{ product.name }}</h3>
      <h4>{{ product.price | currency }}</h4>
      <p>{{ product.description }}</p>
    
    </div>
        

    這行 <h4>{{ product.price | currency }}</h4> 使用 currency 管道來把 product.price 從數字轉換成貨幣字串。管道給了你一種在 HTML 範本中轉換資料的方式。欲知詳情,參閱 Pipes

    The line, <h4>{{ product.price | currency }}</h4>, uses the currency pipe to transform product.price from a number to a currency string. A pipe is a way you can transform data in your HTML template. For more information about Angular pipes, see Pipes.

現在,當用戶點選商品列表中的某個名字時,路由器就會導航到商品的不同網址,用商品詳情元件代替商品列表元件,並顯示商品詳情。

Now, when users click on a name in the product list, the router navigates them to the distinct URL for the product, swaps out the product list component for the product details component, and displays the product details.

要了解關於 Angular 路由器的更多資訊,請參閱路由和導航

For more information about the Angular Router, see Routing & Navigation.

下一步

Next steps

恭喜!你已經把路由整合到你的線上商店了。

Congratulations! You have integrated routing into your online store.

  • 從商品列表頁面連結到了單個商品。

    Products are linked from the product list view to individual products.

  • 使用者可以點選列表中的某個商品名稱來在新檢視中檢視其詳細資訊,並帶有顯著的 URL/路由。

    Users can click on a product name from the list to see details in a new view, with a distinct URL/route.

要繼續探索 Angular,請選擇以下選項之一:

To continue exploring Angular, choose either of the following options: