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

應用內導航:路由到檢視

In-app navigation: routing to views

在單頁面應用中,你可以透過顯示或隱藏特定元件的顯示部分來改變使用者能看到的內容,而不用去伺服器獲取新頁面。當用戶執行應用任務時,他們要在你預定義的不同檢視之間移動。要想在應用的單個頁面中實現這種導航,你可以使用 Angular 的Router(路由器)。

In a single-page app, you change what the user sees by showing or hiding portions of the display that correspond to particular components, rather than going out to the server to get a new page. As users perform application tasks, they need to move between the different views that you have defined.

為了處理從一個檢視到下一個檢視之間的導航,你可以使用 Angular 的路由器。路由器會把瀏覽器 URL 解釋成改變檢視的操作指南,以完成導航。

To handle the navigation from one view to the next, you use the Angular Router. The Routerenables navigation by interpreting a browser URL as an instruction to change the view.

要探索一個具備路由器主要功能的範例應用,請參閱現場演練 / 下載範例

To explore a sample app featuring the router's primary features, see the現場演練 / 下載範例.

先決條件

Prerequisites

在建立路由之前,你應該熟悉以下內容:

Before creating a route, you should be familiar with the following:

關於這個現成應用的 Angular 簡介,請參閱快速上手。關於建構 Angular 應用的更深入體驗,請參閱英雄之旅課程。兩者都會指導你使用元件類別和範本。

For an introduction to Angular with a ready-made app, see Getting Started. For a more in-depth experience of building an Angular app, see the Tour of Heroes tutorial. Both guide you through using component classes and templates.


產生一個支援路由的應用

Generate an app with routing enabled

下面的命令會用 Angular CLI 來產生一個帶有應用路由模組(AppRoutingModule)的基本 Angular 應用,它是一個 NgModule,可用來配置路由。下面的例子中應用的名字是 routing-app

The following command uses the Angular CLI to generate a basic Angular app with an app routing module, called AppRoutingModule, which is an NgModule where you can configure your routes. The app name in the following example is routing-app.

ng new routing-app --routing
      
      ng new routing-app --routing
    

一旦產生新應用,CLI 就會提示你選擇 CSS 或 CSS 前處理器。在這個例子中,我們接受 CSS 的預設值。

When generating a new app, the CLI prompts you to select CSS or a CSS preprocessor. For this example, accept the default of CSS.

為路由新增元件

Adding components for routing

為了使用 Angular 的路由器,應用至少要有兩個元件才能從一個導航到另一個。要使用 CLI 建立元件,請在命令列輸入以下內容,其中 first 是元件的名稱:

To use the Angular router, an app needs to have at least two components so that it can navigate from one to the other. To create a component using the CLI, enter the following at the command line where first is the name of your component:

ng generate component first
      
      ng generate component first
    

為第二個元件重複這個步驟,但給它一個不同的名字。這裡的新名字是 second

Repeat this step for a second component but give it a different name. Here, the new name is second.

ng generate component second
      
      ng generate component second
    

CLI 會自動新增 Component 字尾,所以如果在編寫 first-component,那麼其元件名就是 FirstComponentComponent

The CLI automatically appends Component, so if you were to write first-component, your component would be FirstComponentComponent.

<base href>

本指南適用於 CLI 產生的 Angular 應用。如果你是手動工作的,請確保你的 index.html 檔案的 <head> 中有 <base href="/"> 語句。這裡假定 app 資料夾是應用的根目錄,並使用 "/" 作為基礎路徑。

This guide works with a CLI-generated Angular app. If you are working manually, make sure that you have <base href="/"> in the <head> of your index.html file. This assumes that the app folder is the application root, and uses "/".

匯入這些新元件

Importing your new components

要使用這些新元件,請把它們匯入到該檔案頂部的 AppRoutingModule 中,具體如下:

To use your new components, import them into AppRoutingModule at the top of the file, as follows:

import { FirstComponent } from './first/first.component'; import { SecondComponent } from './second/second.component';
AppRoutingModule (excerpt)
      
      import { FirstComponent } from './first/first.component';
import { SecondComponent } from './second/second.component';
    

定義一個基本路由

Defining a basic route

建立路由有三個基本的建構塊。

There are three fundamental building blocks to creating a route.

AppRoutingModule 匯入 AppModule 並把它新增到 imports 陣列中。

Import the AppRoutingModule into AppModule and add it to the imports array.

Angular CLI 會為你執行這一步驟。但是,如果要手動建立應用或使用現存的非 CLI 應用,請驗證匯入和配置是否正確。下面是使用 --routing 標誌產生的預設 AppModule

The Angular CLI performs this step for you. However, if you are creating an app manually or working with an existing, non-CLI app, verify that the imports and configuration are correct. The following is the default AppModule using the CLI with the --routing flag.

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; // CLI imports AppRoutingModule import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule // CLI adds AppRoutingModule to the AppModule's imports array ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Default CLI AppModule with routing
      
      import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module'; // CLI imports AppRoutingModule
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule // CLI adds AppRoutingModule to the AppModule's imports array
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
    
  1. RouterModuleRoutes 匯入到你的路由模組中。

    Import RouterModule and Routes into your routing module.

    Angular CLI 會自動執行這一步驟。CLI 還為你的路由設定了 Routes 陣列,並為 @NgModule() 配置了 importsexports 陣列。

    The Angular CLI performs this step automatically. The CLI also sets up a Routes array for your routes and configures the imports and exports arrays for @NgModule().

    import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; // CLI imports router const routes: Routes = []; // sets up routes constant where you define your routes // configures NgModule imports and exports @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
    CLI app routing module
          
          import { NgModule } from '@angular/core';
    import { Routes, RouterModule } from '@angular/router'; // CLI imports router
    
    const routes: Routes = []; // sets up routes constant where you define your routes
    
    // configures NgModule imports and exports
    @NgModule({
      imports: [RouterModule.forRoot(routes)],
      exports: [RouterModule]
    })
    export class AppRoutingModule { }
        
  2. Routes 陣列中定義你的路由。

    Define your routes in your Routes array.

    這個陣列中的每個路由都是一個包含兩個屬性的 JavaScript 物件。第一個屬性 path 定義了該路由的 URL 路徑。第二個屬性 component 定義了要讓 Angular 用作相應路徑的元件。

    Each route in this array is a JavaScript object that contains two properties. The first property, path, defines the URL path for the route. The second property, component, defines the component Angular should use for the corresponding path.

const routes: Routes = [ { path: 'first-component', component: FirstComponent }, { path: 'second-component', component: SecondComponent }, ];
AppRoutingModule (excerpt)
      
      const routes: Routes = [
  { path: 'first-component', component: FirstComponent },
  { path: 'second-component', component: SecondComponent },
];
    
  1. 把這些路由新增到你的應用中。

    Add your routes to your application.

    現在你已經定義了路由,可以把它們新增到應用中了。首先,新增到這兩個元件的連結。把要新增路由的連結賦值給 routerLink 屬性。將屬性的值設定為該元件,以便在使用者點選各個連結時顯示這個值。接下來,修改元件範本以包含 <router-outlet> 標籤。該元素會通知 Angular,你可以用所選路由的元件更新應用的檢視。

    Now that you have defined your routes, you can add them to your application. First, add links to the two components. Assign the anchor tag that you want to add the route to the routerLink attribute. Set the value of the attribute to the component to show when a user clicks on each link. Next, update your component template to include <router-outlet>. This element informs Angular to update the application view with the component for the selected route.

    <h1>Angular Router App</h1> <!-- This nav gives you links to click, which tells the router which route to use (defined in the routes constant in AppRoutingModule) --> <nav> <ul> <li><a routerLink="/first-component" routerLinkActive="active">First Component</a></li> <li><a routerLink="/second-component" routerLinkActive="active">Second Component</a></li> </ul> </nav> <!-- The routed views render in the <router-outlet>--> <router-outlet></router-outlet>
    Template with routerLink and router-outlet
          
          <h1>Angular Router App</h1>
    <!-- This nav gives you links to click, which tells the router which route to use (defined in the routes constant in  AppRoutingModule) -->
    <nav>
      <ul>
        <li><a routerLink="/first-component" routerLinkActive="active">First Component</a></li>
        <li><a routerLink="/second-component" routerLinkActive="active">Second Component</a></li>
      </ul>
    </nav>
    <!-- The routed views render in the <router-outlet>-->
    <router-outlet></router-outlet>
        

路由順序

Route order

路由的順序很重要,因為 Router 在匹配路由時使用“先到先得”策略,所以應該在不那麼具體的路由前面放置更具體的路由。首先列出靜態路徑的路由,然後是一個與預設路由匹配的空路徑路由。萬用字元路由是最後一個,因為它匹配每一個 URL,只有當其它路由都沒有匹配時,Router 才會選擇它。

The order of routes is important because the Router uses a first-match wins strategy when matching routes, so more specific routes should be placed above less specific routes. List routes with a static path first, followed by an empty path route, which matches the default route. The wildcard route comes last because it matches every URL and the Router selects it only if no other routes match first.

獲取路由資訊

Getting route information

通常,當用戶導航你的應用時,你會希望把資訊從一個元件傳遞到另一個元件。例如,考慮一個顯示雜貨商品購物清單的應用。列表中的每一項都有一個唯一的 id。要想編輯某個專案,使用者需要單擊“編輯”按鈕,開啟一個 EditGroceryItem 元件。你希望該元件得到該商品的 id,以便它能向用戶顯示正確的資訊。

Often, as a user navigates your application, you want to pass information from one component to another. For example, consider an application that displays a shopping list of grocery items. Each item in the list has a unique id. To edit an item, users click an Edit button, which opens an EditGroceryItem component. You want that component to retrieve the id for the grocery item so it can display the right information to the user.

你也可以使用一個路由把這種型別的資訊傳給你的應用元件。要做到這一點,你可以使用 ActivatedRoute 介面。

You can use a route to pass this type of information to your application components. To do so, you use the ActivatedRoute interface.

要從路由中獲取資訊:

To get information from a route:

  1. ActivatedRouteParamMap 匯入你的元件。

    Import ActivatedRoute and ParamMap to your component.

    import { Router, ActivatedRoute, ParamMap } from '@angular/router';
    In the component class (excerpt)
          
          import { Router, ActivatedRoute, ParamMap } from '@angular/router';
        

    這些 import 語句添加了元件所需的幾個重要元素。要詳細瞭解每個 API,請參閱以下 API 頁面:

    These import statements add several important elements that your component needs. To learn more about each, see the following API pages:

  2. 透過把 ActivatedRoute 的一個實例新增到你的應用的建構函式中來注入它:

    Inject an instance of ActivatedRoute by adding it to your application's constructor:

    constructor( private route: ActivatedRoute, ) {}
    In the component class (excerpt)
          
          constructor(
      private route: ActivatedRoute,
    ) {}
        
  3. 更新 ngOnInit() 方法來訪問這個 ActivatedRoute 並追蹤 id 引數:

    Update the ngOnInit() method to access the ActivatedRoute and track the id parameter:

    ngOnInit() { this.route.queryParams.subscribe(params => { this.name = params['name']; }); }
    In the component (excerpt)
          
          ngOnInit() {
      this.route.queryParams.subscribe(params => {
        this.name = params['name'];
      });
    }
        

    注意:前面的例子使用了一個變數 name,並根據 name 引數給它賦值。

    Note: The preceding example uses a variable, name, and assigns it the value based on the name parameter.

設定萬用字元路由

Setting up wildcard routes

當用戶試圖導航到那些不存在的應用部件時,在正常的應用中應該能得到很好的處理。要在應用中新增此功能,需要設定萬用字元路由。當所請求的 URL 與任何路由器路徑都不匹配時,Angular 路由器就會選擇這個路由。

A well-functioning application should gracefully handle when users attempt to navigate to a part of your application that does not exist. To add this functionality to your application, you set up a wildcard route. The Angular router selects this route any time the requested URL doesn't match any router paths.

要設定萬用字元路由,請在 routes 定義中新增以下程式碼。

To set up a wildcard route, add the following code to your routes definition.

{ path: '**', component:}
AppRoutingModule (excerpt)
      
      { path: '**', component:  }

    

這兩個星號 ** 告訴 Angular,這個 routes 定義是萬用字元路由。對於 component 屬性,你可以使用應用中的任何元件。常見的選擇包括應用專屬的 PageNotFoundComponent,你可以定義它來向用戶展示 404 頁面,或者跳轉到應用的主元件。萬用字元路由是最後一個路由,因為它匹配所有的 URL。關於路由順序的更多詳細資訊,請參閱路由順序

The two asterisks, **, indicate to Angular that this routes definition is a wildcard route. For the component property, you can define any component in your application. Common choices include an application-specific PageNotFoundComponent, which you can define to display a 404 page to your users; or a redirect to your application's main component. A wildcard route is the last route because it matches any URL. For more detail on why order matters for routes, see Route order.

顯示 404 頁面

Displaying a 404 page

要顯示 404 頁面,請設定一個萬用字元路由,並將 component 屬性設定為你要用於 404 頁面的元件,如下所示:

To display a 404 page, set up a wildcard route with the component property set to the component you'd like to use for your 404 page as follows:

const routes: Routes = [ { path: 'first-component', component: FirstComponent }, { path: 'second-component', component: SecondComponent }, { path: '**', component: PageNotFoundComponent }, // Wildcard route for a 404 page ];
AppRoutingModule (excerpt)
      
      const routes: Routes = [
  { path: 'first-component', component: FirstComponent },
  { path: 'second-component', component: SecondComponent },
  { path: '**', component: PageNotFoundComponent },  // Wildcard route for a 404 page
];
    

path** 的最後一條路由是萬用字元路由。如果請求的 URL 與前面列出的路徑不匹配,路由器會選擇這個路由,並把該使用者送到 PageNotFoundComponent

The last route with the path of ** is a wildcard route. The router selects this route if the requested URL doesn't match any of the paths earlier in the list and sends the user to the PageNotFoundComponent.

設定重新導向

Setting up redirects

要設定重新導向,請使用重新導向源的 path、要重新導向目標的 component 和一個 pathMatch 值來配置路由,以告訴路由器該如何匹配 URL。

To set up a redirect, configure a route with the path you want to redirect from, the component you want to redirect to, and a pathMatch value that tells the router how to match the URL.

const routes: Routes = [ { path: 'first-component', component: FirstComponent }, { path: 'second-component', component: SecondComponent }, { path: '', redirectTo: '/first-component', pathMatch: 'full' }, // redirect to `first-component` { path: '**', component: PageNotFoundComponent }, // Wildcard route for a 404 page ];
AppRoutingModule (excerpt)
      
      const routes: Routes = [
  { path: 'first-component', component: FirstComponent },
  { path: 'second-component', component: SecondComponent },
  { path: '',   redirectTo: '/first-component', pathMatch: 'full' }, // redirect to `first-component`
  { path: '**', component: PageNotFoundComponent },  // Wildcard route for a 404 page
];
    

在這個例子中,第三個路由是重新導向路由,所以路由器會預設跳到 first-component 路由。注意,這個重新導向路由位於萬用字元路由之前。這裡的 path: '' 表示使用初始的相對 URL( '' )。

In this example, the third route is a redirect so that the router defaults to the first-component route. Notice that this redirect precedes the wildcard route. Here, path: '' means to use the initial relative URL ('').

關於 pathMatch 的詳情,請參閱聚焦 pathMatch部分。

For more details on pathMatch see Spotlight on pathMatch.

巢狀路由

Nesting routes

隨著你的應用變得越來越複雜,你可能要建立一些根元件之外的相對路由。這些巢狀路由型別稱為子路由。這意味著你要為你的應用新增第二 <router-outlet>,因為它是 AppComponent 之外的另一個 <router-outlet>

As your application grows more complex, you may want to create routes that are relative to a component other than your root component. These types of nested routes are called child routes. This means you're adding a second <router-outlet> to your app, because it is in addition to the <router-outlet> in AppComponent.

在這個例子中,還有兩個子元件,child-achild-b。這裡的 FirstComponent 有它自己的 <nav>AppComponent 之外的第二 <router-outlet>

In this example, there are two additional child components, child-a, and child-b. Here, FirstComponent has its own <nav> and a second <router-outlet> in addition to the one in AppComponent.

<h2>First Component</h2> <nav> <ul> <li><a routerLink="child-a">Child A</a></li> <li><a routerLink="child-b">Child B</a></li> </ul> </nav> <router-outlet></router-outlet>
In the template
      
      <h2>First Component</h2>

<nav>
  <ul>
    <li><a routerLink="child-a">Child A</a></li>
    <li><a routerLink="child-b">Child B</a></li>
  </ul>
</nav>

<router-outlet></router-outlet>
    

子路由和其它路由一樣,同時需要 pathcomponent。唯一的區別是你要把子路由放在父路由的 children 陣列中。

A child route is like any other route, in that it needs both a path and a component. The one difference is that you place child routes in a children array within the parent route.

const routes: Routes = [ { path: 'first-component', component: FirstComponent, // this is the component with the <router-outlet> in the template children: [ { path: 'child-a', // child route path component: ChildAComponent, // child route component that the router renders }, { path: 'child-b', component: ChildBComponent, // another child route component that the router renders }, ], }, ];
AppRoutingModule (excerpt)
      
      const routes: Routes = [
  {
    path: 'first-component',
    component: FirstComponent, // this is the component with the <router-outlet> in the template
    children: [
      {
        path: 'child-a', // child route path
        component: ChildAComponent, // child route component that the router renders
      },
      {
        path: 'child-b',
        component: ChildBComponent, // another child route component that the router renders
      },
    ],
  },
];
    

使用相對路徑

Using relative paths

相對路徑允許你定義相對於當前 URL 段的路徑。下面的例子展示了到另一個元件 second-component 的相對路由。FirstComponentSecondComponent 在樹中處於同一級別,但是,指向 SecondComponent 的連結位於 FirstComponent 中,這意味著路由器必須先上升一個級別,然後進入二級目錄才能找到 SecondComponent。你可以使用 ../ 符號來上升一個級別,而不用寫出到 SecondComponent 的完整路徑。

Relative paths allow you to define paths that are relative to the current URL segment. The following example shows a relative route to another component, second-component. FirstComponent and SecondComponent are at the same level in the tree, however, the link to SecondComponent is situated within the FirstComponent, meaning that the router has to go up a level and then into the second directory to find the SecondComponent. Rather than writing out the whole path to get to SecondComponent, you can use the ../ notation to go up a level.

<h2>First Component</h2> <nav> <ul> <li><a routerLink="../second-component">Relative Route to second component</a></li> </ul> </nav> <router-outlet></router-outlet>
In the template
      
      <h2>First Component</h2>

<nav>
  <ul>
    <li><a routerLink="../second-component">Relative Route to second component</a></li>
  </ul>
</nav>
<router-outlet></router-outlet>
    

除了 ../,還可以使用 ./ 或者不帶前導斜槓來指定當前級別。

In addition to ../, you can use ./ or no leading slash to specify the current level.

指定相對路由

Specifying a relative route

要指定相對路由,請使用 NavigationExtras 中的 relativeTo 屬性。在元件類別中,從 @angular/router 匯入 NavigationExtras

To specify a relative route, use the NavigationExtras relativeTo property. In the component class, import NavigationExtras from the @angular/router.

然後在導航方法中使用 relativeTo 引數。在連結引數陣列(它包含 items)之後新增一個物件,把該物件的 relativeTo 屬性設定為當前的 ActivatedRoute,也就是 this.route

Then use relativeTo in your navigation method. After the link parameters array, which here contains items, add an object with the relativeTo property set to the ActivatedRoute, which is this.route.

goToItems() { this.router.navigate(['items'], { relativeTo: this.route }); }
RelativeTo
      
      goToItems() {
  this.router.navigate(['items'], { relativeTo: this.route });
}
    

goToItems() 方法會把目標 URI 解釋為相對於當前路由的,並導航到 items 路由。

The goToItems() method interprets the destination URI as relative to the activated route and navigates to the items route.

訪問查詢引數和片段

Accessing query parameters and fragments

有時,應用中的某個特性需要訪問路由的部件,比如查詢引數或片段(fragment)。本課程的這個階段使用了一個“英雄之旅”中的列表檢視,你可以在其中點選一個英雄來檢視詳情。路由器使用 id 來顯示正確的英雄的詳情。

Sometimes, a feature of your application requires accessing a part of a route, such as a query parameter or a fragment. The Tour of Heroes app at this stage in the tutorial uses a list view in which you can click on a hero to see details. The router uses an id to show the correct hero's details.

首先,在要導航的元件中匯入以下成員。

First, import the following members in the component you want to navigate from.

import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs'; import { switchMap } from 'rxjs/operators';
Component import statements (excerpt)
      
      import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
    

接下來,注入當前路由(ActivatedRoute)服務:

Next inject the activated route service:

constructor(private route: ActivatedRoute) {}
Component (excerpt)
      
      constructor(private route: ActivatedRoute) {}
    

配置這個類別,讓你有一個可觀察物件 heroes$、一個用來儲存英雄的 id 號的 selectedId,以及 ngOnInit() 中的英雄們,新增下面的程式碼來獲取所選英雄的 id。這個程式碼片段假設你有一個英雄列表、一個英雄服務、一個能獲取你的英雄的函式,以及用來渲染你的列表和細節的 HTML,就像在《英雄之旅》例子中一樣。

Configure the class so that you have an observable, heroes$, a selectedId to hold the id number of the hero, and the heroes in the ngOnInit(), add the following code to get the id of the selected hero. This code snippet assumes that you have a heroes list, a hero service, a function to get your heroes, and the HTML to render your list and details, just as in the Tour of Heroes example.

heroes$: Observable; selectedId: number; heroes = HEROES; ngOnInit() { this.heroes$ = this.route.paramMap.pipe( switchMap(params => { this.selectedId = Number(params.get('id')); return this.service.getHeroes(); }) ); }
Component 1 (excerpt)
      
      heroes$: Observable;
selectedId: number;
heroes = HEROES;

ngOnInit() {
  this.heroes$ = this.route.paramMap.pipe(
    switchMap(params => {
      this.selectedId = Number(params.get('id'));
      return this.service.getHeroes();
    })
  );
}

    

接下來,在要導航到的元件中,匯入以下成員。

Next, in the component that you want to navigate to, import the following members.

import { Router, ActivatedRoute, ParamMap } from '@angular/router'; import { Observable } from 'rxjs';
Component 2 (excerpt)
      
      import { Router, ActivatedRoute, ParamMap } from '@angular/router';
import { Observable } from 'rxjs';
    

在元件類別的建構函式中注入 ActivatedRouteRouter,這樣在這個元件中就可以用它們了:

Inject ActivatedRoute and Router in the constructor of the component class so they are available to this component:

hero$: Observable; constructor( private route: ActivatedRoute, private router: Router ) {} ngOnInit() { const heroId = this.route.snapshot.paramMap.get('id'); this.hero$ = this.service.getHero(heroId); } gotoItems(hero: Hero) { const heroId = hero ? hero.id : null; // Pass along the hero id if available // so that the HeroList component can select that item. this.router.navigate(['/heroes', { id: heroId }]); }
Component 2 (excerpt)
      
      hero$: Observable;

  constructor(
    private route: ActivatedRoute,
    private router: Router  ) {}

  ngOnInit() {
    const heroId = this.route.snapshot.paramMap.get('id');
    this.hero$ = this.service.getHero(heroId);
  }

  gotoItems(hero: Hero) {
    const heroId = hero ? hero.id : null;
    // Pass along the hero id if available
    // so that the HeroList component can select that item.
    this.router.navigate(['/heroes', { id: heroId }]);
  }

    

延遲載入

Lazy loading

你可以配置路由定義來實現延遲載入模組,這意味著 Angular 只會在需要時才載入這些模組,而不是在應用啟動時就載入全部。 另外,你可以在後臺預載入一些應用部件來改善使用者體驗。

You can configure your routes to lazy load modules, which means that Angular only loads modules as needed, rather than loading all modules when the app launches. Additionally, you can preload parts of your app in the background to improve the user experience.

關於延遲載入和預載入的詳情,請參閱專門的指南延遲載入 NgModule

For more information on lazy loading and preloading see the dedicated guide Lazy loading NgModules.

防止未經授權的訪問

Preventing unauthorized access

使用路由守衛來防止使用者未經授權就導航到應用的某些部分。Angular 中提供了以下路由守衛:

Use route guards to prevent users from navigating to parts of an app without authorization. The following route guards are available in Angular:

要想使用路由守衛,可以考慮使用無元件路由,因為這對於保護子路由很方便。

To use route guards, consider using component-less routes as this facilitates guarding child routes.

為你的守衛建立一項服務:

Create a service for your guard:

ng generate guard your-guard
      
      ng generate guard your-guard
    

請在守衛類別裡實現你要用到的守衛。下面的例子使用 CanActivate 來保護該路由。

In your guard class, implement the guard you want to use. The following example uses CanActivate to guard the route.

export class YourGuard implements CanActivate { canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { // your logic goes here } }
Component (excerpt)
      
      export class YourGuard implements CanActivate {
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): boolean {
      // your  logic goes here
  }
}
    

在路由模組中,在 routes 配置中使用相應的屬性。這裡的 canActivate 會告訴路由器它要協調到這個特定路由的導航。

In your routing module, use the appropriate property in your routes configuration. Here, canActivate tells the router to mediate navigation to this particular route.

{ path: '/your-path', component: YourComponent, canActivate: [YourGuard], }
Routing module (excerpt)
      
      {
  path: '/your-path',
  component: YourComponent,
  canActivate: [YourGuard],
}
    

關於此可工作範例的更多資訊,請參閱路由導航中關於路由守衛的部分

For more information with a working example, see the routing tutorial section on route guards.

連結引數陣列儲存路由導航時所需的成分:

A link parameters array holds the following ingredients for router navigation:

  • 指向目標元件的那個路由的路徑(path)

    The path of the route to the destination component.

  • 必備路由引數和可選路由引數,它們將進入該路由的 URL

    Required and optional route parameters that go into the route URL.

你可以把 RouterLink 指令繫結到一個數組,就像這樣:

You can bind the RouterLink directive to such an array like this:

<a [routerLink]="['/heroes']">Heroes</a>
src/app/app.component.ts (h-anchor)
      
      <a [routerLink]="['/heroes']">Heroes</a>
    

在指定路由引數時,使用如下的兩元素陣列:

The following is a two-element array when specifying a route parameter:

<a [routerLink]="['/hero', hero.id]"> <span class="badge">{{ hero.id }}</span>{{ hero.name }} </a>
src/app/heroes/hero-list/hero-list.component.html (nav-to-detail)
      
      <a [routerLink]="['/hero', hero.id]">
  <span class="badge">{{ hero.id }}</span>{{ hero.name }}
</a>
    

你可以在物件中提供可選的路由引數,比如 { foo: 'foo' }

You can provide optional route parameters in an object, as in { foo: 'foo' }:

<a [routerLink]="['/crisis-center', { foo: 'foo' }]">Crisis Center</a>
src/app/app.component.ts (cc-query-params)
      
      <a [routerLink]="['/crisis-center', { foo: 'foo' }]">Crisis Center</a>
    

這三個例子涵蓋了你在單級路由的應用中所需的一切。不過,在你新增一個像危機中心一樣的子路由時,你可以建立新連結陣列。

These three examples cover the needs of an app with one level of routing. However, with a child router, such as in the crisis center, you create new link array possibilities.

下面這個最小化 RouterLink 例子是基於危機中心指定的預設子路由建構的。

The following minimal RouterLink example builds upon a specified default child route for the crisis center.

<a [routerLink]="['/crisis-center']">Crisis Center</a>
src/app/app.component.ts (cc-anchor-w-default)
      
      <a [routerLink]="['/crisis-center']">Crisis Center</a>
    

請注意以下事項:

Note the following:

  • 陣列中的第一個條目標記出了父路由(/crisis-center)。

    The first item in the array identifies the parent route (/crisis-center).

  • 這個父路由沒有引數。

    There are no parameters for this parent route.

  • 沒有預設的子路由,因此你得選取一個。

    There is no default for the child route so you need to pick one.

  • 你決定跳轉到 CrisisListComponent,它的路由路徑是'/',但你不用顯式的新增它。

    You're navigating to the CrisisListComponent, whose route path is /, but you don't need to explicitly add the slash.

考慮以下路由器連結,它將從應用的根目錄導航到巨龍危機(Dragon Crisis):

Consider the following router link that navigates from the root of the application down to the Dragon Crisis:

<a [routerLink]="['/crisis-center', 1]">Dragon Crisis</a>
src/app/app.component.ts (Dragon-anchor)
      
      <a [routerLink]="['/crisis-center', 1]">Dragon Crisis</a>
    
  • 陣列中的第一個條目標記出了父路由(/crisis-center)。

    The first item in the array identifies the parent route (/crisis-center).

  • 這個父路由沒有引數。

    There are no parameters for this parent route.

  • 陣列中的第二個條目('/:id')用來標記出到指定危機的詳情頁的子路由。

    The second item identifies the child route details about a particular crisis (/:id).

  • 詳細的子路由需要一個 id 路由引數。

    The details child route requires an id route parameter.

  • 你把巨龍危機id 新增為該陣列中的第二個條目(1)。

    You added the id of the Dragon Crisis as the second item in the array (1).

  • 最終產生的路徑是 /crisis-center/1

    The resulting path is /crisis-center/1.

你也可以把危機中心的路由單獨重新定義為 AppComponent 的範本:

You could also redefine the AppComponent template with Crisis Center routes exclusively:

template: ` <h1 class="title">Angular Router</h1> <nav> <a [routerLink]="['/crisis-center']">Crisis Center</a> <a [routerLink]="['/crisis-center/1', { foo: 'foo' }]">Dragon Crisis</a> <a [routerLink]="['/crisis-center/2']">Shark Crisis</a> </nav> <router-outlet></router-outlet> `
src/app/app.component.ts (template)
      
      template: `
  <h1 class="title">Angular Router</h1>
  <nav>
    <a [routerLink]="['/crisis-center']">Crisis Center</a>
    <a [routerLink]="['/crisis-center/1', { foo: 'foo' }]">Dragon Crisis</a>
    <a [routerLink]="['/crisis-center/2']">Shark Crisis</a>
  </nav>
  <router-outlet></router-outlet>
`
    

總之,你可以用一級、兩級或多級路由來寫應用程式。 連結引數陣列提供了用來表示任意深度路由的連結引數陣列以及任意合法的路由引數序列、必須的路由器引數以及可選的路由引數物件。

In summary, you can write applications with one, two or more levels of routing. The link parameters array affords the flexibility to represent any routing depth and any legal sequence of route paths, (required) router parameters, and (optional) route parameter objects.

LocationStrategy 和瀏覽器的網址樣式

LocationStrategy and browser URL styles

當路由器導航到一個新的元件檢視時,它會用該檢視的 URL 來更新瀏覽器的當前地址以及歷史。 嚴格來說,這個 URL 其實是本地的,瀏覽器不會把該 URL 發給伺服器,並且不會重新載入此頁面。

When the router navigates to a new component view, it updates the browser's location and history with a URL for that view. As this is a strictly local URL the browser won't send this URL to the server and will not reload the page.

現代 HTML 5 瀏覽器支援history.pushState API, 這是一項可以改變瀏覽器的當前地址和歷史,卻又不會觸發伺服器端頁面請求的技術。 路由器可以合成出一個“自然的”URL,它看起來和那些需要進行頁面載入的 URL 沒什麼區別。

Modern HTML5 browsers support history.pushState, a technique that changes a browser's location and history without triggering a server page request. The router can compose a "natural" URL that is indistinguishable from one that would otherwise require a page load.

下面是危機中心的 URL 在“HTML 5 pushState”風格下的樣子:

Here's the Crisis Center URL in this "HTML5 pushState" style:

localhost:3002/crisis-center/
      
      localhost:3002/crisis-center/
    

老舊的瀏覽器在當前地址的 URL 變化時總會往伺服器傳送頁面請求……唯一的例外規則是:當這些變化位於“#”(被稱為“hash”)後面時不會發送。透過把應用內的路由 URL 拼接在 # 之後,路由器可以獲得這條“例外規則”帶來的優點。下面是到危機中心路由的“hash URL”:

Older browsers send page requests to the server when the location URL changes unless the change occurs after a "#" (called the "hash"). Routers can take advantage of this exception by composing in-application route URLs with hashes. Here's a "hash URL" that routes to the Crisis Center.

localhost:3002/src/#/crisis-center/
      
      localhost:3002/src/#/crisis-center/
    

路由器透過兩種 LocationStrategy 提供者來支援所有這些風格:

The router supports both styles with two LocationStrategy providers:

  1. PathLocationStrategy - 預設的策略,支援“HTML 5 pushState”風格。

    PathLocationStrategy—the default "HTML5 pushState" style.

  2. HashLocationStrategy - 支援“hash URL”風格。

    HashLocationStrategy—the "hash URL" style.

RouterModule.forRoot() 函式把 LocationStrategy 設定成了 PathLocationStrategy,使其成為了預設策略。 你還可以在啟動過程中改寫(override)它,來切換到 HashLocationStrategy 風格。

The RouterModule.forRoot() function sets the LocationStrategy to the PathLocationStrategy, which makes it the default strategy. You also have the option of switching to the HashLocationStrategy with an override during the bootstrapping process.

關於提供程式和引導過程的更多資訊,請參閱依賴注入

For more information on providers and the bootstrap process, see Dependency Injection.

選擇路由策略

Choosing a routing strategy

你必須在開發專案的早期就選擇一種路由策略,因為一旦該應用進入了生產階段,你網站的訪問者就會使用並依賴應用的這些 URL 參考。

You must choose a routing strategy early in the development of you project because once the application is in production, visitors to your site use and depend on application URL references.

幾乎所有的 Angular 專案都會使用預設的 HTML 5 風格。它產生的 URL 更易於被使用者理解,它也為將來做伺服器端渲染預留了空間。

Almost all Angular projects should use the default HTML5 style. It produces URLs that are easier for users to understand and it preserves the option to do server-side rendering.

在伺服器端渲染指定的頁面,是一項可以在該應用首次載入時大幅提升響應速度的技術。那些原本需要十秒甚至更長時間載入的應用,可以預先在伺服器端渲染好,並在少於一秒的時間內完整渲染在使用者的裝置上。

Rendering critical pages on the server is a technique that can greatly improve perceived responsiveness when the app first loads. An app that would otherwise take ten or more seconds to start could be rendered on the server and delivered to the user's device in less than a second.

只有當應用的 URL 看起來像是標準的 Web URL,中間沒有 hash(#)時,這個選項才能生效。

This option is only available if application URLs look like normal web URLs without hashes (#) in the middle.

<base href>

路由器使用瀏覽器的 history.pushState API 進行導航。藉助 pushState 你自訂應用中的 URL 路徑 localhost:4200/crisis-center,應用內的 URL 和伺服器的 URL 沒有區別。

The router uses the browser's history.pushState for navigation. pushState allows you to customize in-app URL paths; for example, localhost:4200/crisis-center. The in-app URLs can be indistinguishable from server URLs.

現代的 HTML5 瀏覽器都支援 pushState,這也就是為什麼很多人把這種 URL 形式稱為 "HTML 5" 風格的 URL。

Modern HTML5 browsers were the first to support pushState which is why many people refer to these URLs as "HTML5 style" URLs.

路由器預設使用 HTML5 風格的導航。 在 LocationStrategy 與瀏覽器 URL 風格部分,你可以瞭解為何推薦使用 HTML5 風格的 URL,如何調整其行為,以及必要時如何切換到老式的 hash(#)風格。

HTML5 style navigation is the router default. In the LocationStrategy and browser URL styles section, learn why HTML5 style is preferable, how to adjust its behavior, and how to switch to the older hash (#) style, if necessary.

你必須在應用的 index.html新增一個 <base href> 元素才能讓 pushState 路由正常工作。 瀏覽器要用 <base href> 的值為參考 CSS、指令碼和圖片檔案時使用的相對 URL 新增字首。

You must add a <base href> element to the app's index.html for pushState routing to work. The browser uses the <base href> value to prefix relative URLs when referencing CSS files, scripts, and images.

請把 <base> 元素新增在 <head> 標籤的緊後面。如果應用的根目錄是 app 目錄,那麼就可以像這個應用程式一樣,設定 index.html中的 href 值。程式碼如下。

Add the <base> element just after the <head> tag. If the app folder is the application root, as it is for this application, set the href value in index.html as shown here.

<base href="/">
src/index.html (base-href)
      
      <base href="/">
    

HTML5 網址和 <base href>

HTML5 URLs and the <base href>

後面的指南中會參考 URL 的不同部分。下圖是這些部分所指內容的梗概:

The guidelines that follow will refer to different parts of a URL. This diagram outlines what those parts refer to:

foo://example.com:8042/over/there?name=ferret#nose \_/ \______________/\_________/ \_________/ \__/ | | | | | scheme authority path query fragment
      
      foo://example.com:8042/over/there?name=ferret#nose
\_/   \______________/\_________/ \_________/ \__/
 |           |            |            |        |
scheme    authority      path        query   fragment
    

由於路由器預設使用 “HTML 5 pushState” 風格,所以你必須用一個 <base href> 來配置該策略(Strategy)。

While the router uses the HTML5 pushState style by default, you must configure that strategy with a <base href>.

配置該策略的首選方式是往 index.html<head> 中新增一個<base href> element標籤。

The preferred way to configure the strategy is to add a <base href> element tag in the <head> of the index.html.

<base href="/">
src/index.html (base-href)
      
      <base href="/">
    

如果沒有該標記,瀏覽器就可能無法在“深度連結”進入應用時載入資源(圖片,CSS,指令碼)。

Without that tag, the browser may not be able to load resources (images, CSS, scripts) when "deep linking" into the app.

有些開發人員可能無法新增 <base> 元素,這可能是因為它們沒有訪問 <head>index.html 的許可權。

Some developers may not be able to add the <base> element, perhaps because they don't have access to <head> or the index.html.

它們仍然可以使用 HTML 5 格式的 URL,但要採取如下步驟進行補救:

Those developers may still use HTML5 URLs by taking the following two steps:

  1. 用適當的[APP_BASE_HREF][]值提供(provide)路由器。

    Provide the router with an appropriate APP_BASE_HREF value.

  2. 對所有 Web 資源(CSS、圖片、指令碼和範本 HTML 檔案)使用根 URL(高優先度 URL)。

    Use root URLs (URLs with an authority) for all web resources: CSS, images, scripts, and template HTML files.

  • <base href>path 應該用 "/" 結尾,瀏覽器會忽略 path 中最右邊的 "/" 後面的字元。

    The <base href> path should end with a "/", as browsers ignore characters in the path that follow the right-most "/".

  • 如果 <base href> 包含 query 部分,則只有頁內連結的 path 部分為空並且沒有 query 時,才會使用這裡的 query。 這意味著 <base href> 中的 query 部分只有在使用 HashLocationStrategy 策略時才有用。

    If the <base href> includes a query part, the query is only used if the path of a link in the page is empty and has no query. This means that a query in the <base href> is only included when using HashLocationStrategy.

  • 如果頁內連結是根 URL(高優先度 URL),則 <base href> 不會使用。在這種方式下,APP_BASE_HREF 的優先度將會導致所有由 Angular 建立的連結忽略 <base href>

    If a link in the page is a root URL (has an authority), the <base href> is not used. In this way, an APP_BASE_HREF with an authority will cause all links created by Angular to ignore the <base href> value.

  • <base href> 中的片段(#後面的部分)永遠不會被使用。

    A fragment in the <base href> is never persisted.

對所有 Web 資源使用絕對地址:CSS、圖片、指令碼、範本 HTML。

For more complete information on how <base href> is used to construct target URIs, see the RFC section on transforming references.

HashLocationStrategy

你可以在根模組的 RouterModule.forRoot() 的第二個引數中傳入一個帶有 useHash: true 的物件,以回到基於 HashLocationStrategy 的傳統方式。

You can use HashLocationStrategy by providing the useHash: true in an object as the second argument of the RouterModule.forRoot() in the AppModule.

import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { Routes, RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component'; const routes: Routes = [ ]; @NgModule({ imports: [ BrowserModule, FormsModule, RouterModule.forRoot(routes, { useHash: true }) // .../#/crisis-center/ ], declarations: [ AppComponent, PageNotFoundComponent ], providers: [ ], bootstrap: [ AppComponent ] }) export class AppModule { }
src/app/app.module.ts (hash URL strategy)
      
      import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';

import { AppComponent } from './app.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

const routes: Routes = [

];

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    RouterModule.forRoot(routes, { useHash: true })  // .../#/crisis-center/
  ],
  declarations: [
    AppComponent,
    PageNotFoundComponent
  ],
  providers: [

  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }
    

路由器參考手冊

Router Reference

下面的部分重點介紹了一些路由器的核心概念。

The folllowing sections highlight some core router concepts.

路由器匯入

Router imports

Angular 的 Router 是一個可選服務,它為指定的 URL 提供特定的元件檢視。它不是 Angular 核心的一部分,因此它位於自己的包 @angular/router 中。

The Angular Router is an optional service that presents a particular component view for a given URL. It is not part of the Angular core and thus is in its own library package, @angular/router.

從任何其它的 Angular 套件中匯入你需要的東西。

Import what you need from it as you would from any other Angular package.

import { RouterModule, Routes } from '@angular/router';
src/app/app.module.ts (import)
      
      import { RouterModule, Routes } from '@angular/router';
    

關於瀏覽器 URL 風格的更多資訊,請參閱 LocationStrategy 和瀏覽器 URL 風格

For more on browser URL styles, see LocationStrategy and browser URL styles.

配置

Configuration

帶路由的 Angular 應用中有一個 Router 服務的單例實例。當瀏覽器的 URL 發生變化時,該路由器會查詢相應的 Route,以便根據它確定要顯示的元件。

A routed Angular application has one singleton instance of the Router service. When the browser's URL changes, that router looks for a corresponding Route from which it can determine the component to display.

在配置之前,路由器沒有任何路由。下面的例子建立了五個路由定義,透過 RouterModule.forRoot() 方法配置路由器,並把結果新增到 AppModuleimports 陣列中。

A router has no routes until you configure it. The following example creates five route definitions, configures the router via the RouterModule.forRoot() method, and adds the result to the AppModule's imports array.

const appRoutes: Routes = [ { path: 'crisis-center', component: CrisisListComponent }, { path: 'hero/:id', component: HeroDetailComponent }, { path: 'heroes', component: HeroListComponent, data: { title: 'Heroes List' } }, { path: '', redirectTo: '/heroes', pathMatch: 'full' }, { path: '**', component: PageNotFoundComponent } ]; @NgModule({ imports: [ RouterModule.forRoot( appRoutes, { enableTracing: true } // <-- debugging purposes only ) // other imports here ], ... }) export class AppModule { }
src/app/app.module.ts (excerpt)
      
      const appRoutes: Routes = [
  { path: 'crisis-center', component: CrisisListComponent },
  { path: 'hero/:id',      component: HeroDetailComponent },
  {
    path: 'heroes',
    component: HeroListComponent,
    data: { title: 'Heroes List' }
  },
  { path: '',
    redirectTo: '/heroes',
    pathMatch: 'full'
  },
  { path: '**', component: PageNotFoundComponent }
];

@NgModule({
  imports: [
    RouterModule.forRoot(
      appRoutes,
      { enableTracing: true } // <-- debugging purposes only
    )
    // other imports here
  ],
  ...
})
export class AppModule { }
    

appRoutes 路由陣列描述瞭如何導航。把它傳給模組的 imports 陣列中的 RouterModule.forRoot() 方法來配置路由器。

The appRoutes array of routes describes how to navigate. Pass it to the RouterModule.forRoot() method in the module imports to configure the router.

每個 Route 都會把一個 URL path 對映到一個元件。路徑中沒有前導斜槓。路由器會為你解析並建構最終的 URL,這樣你就可以在應用檢視中導航時使用相對路徑和絕對路徑了。

Each Route maps a URL path to a component. There are no leading slashes in the path. The router parses and builds the final URL for you, which allows you to use both relative and absolute paths when navigating between application views.

第二個路由中的 :id 是路由引數的令牌。在像 /hero/42 這樣的 URL 中,“42”是 id 引數的值。相應的 HeroDetailComponent 用這個值來查詢並顯示 id 為 42 的英雄。

The :id in the second route is a token for a route parameter. In a URL such as /hero/42, "42" is the value of the id parameter. The corresponding HeroDetailComponent uses that value to find and present the hero whose id is 42.

第三個路由中的 data 屬性是存放與該特定路由關聯的任意資料的地方。每個啟用的路由都可以訪問 data 屬性。可以用它來儲存頁面標題,麵包屑文字和其它唯讀靜態資料等專案。你可以嘗試使用解析器守衛來檢索動態資料。

The data property in the third route is a place to store arbitrary data associated with this specific route. The data property is accessible within each activated route. Use it to store items such as page titles, breadcrumb text, and other read-only, static data. You can use the resolve guard to retrieve dynamic data.

第四個路由中的空路徑表示該應用的預設路徑 - 當 URL 中的路徑為空時通常要去的地方,就像它在剛進來時一樣。這個預設路由重新導向到了 /heroes 這個 URL 的路由,因此會顯示 HeroesListComponent

The empty path in the fourth route represents the default path for the application—the place to go when the path in the URL is empty, as it typically is at the start. This default route redirects to the route for the /heroes URL and, therefore, displays the HeroesListComponent.

如果你需要檢視導航生命週期中發生了什麼事件,可以把 enableTracing 選項作為路由器預設配置的一部分。這會把每個導航生命週期中發生的每個路由器事件都輸出到瀏覽器控制檯中。enableTracing 只會用於除錯目的。你可以把 enableTracing: true 選項作為第二個引數傳給 RouterModule.forRoot() 方法。

If you need to see what events are happening during the navigation lifecycle, there is the enableTracing option as part of the router's default configuration. This outputs each router event that took place during each navigation lifecycle to the browser console. Use enableTracing only for debugging purposes. You set the enableTracing: true option in the object passed as the second argument to the RouterModule.forRoot() method.

路由出口

Router outlet

RouterOutlet 是一個來自路由器函式庫的指令,雖然它的用法像元件一樣。它充當佔位符,用於在範本中標記出路由器應該顯示把該元件顯示在那個出口的位置。

The RouterOutlet is a directive from the router library that is used like a component. It acts as a placeholder that marks the spot in the template where the router should display the components for that outlet.

<router-outlet></router-outlet> <!-- Routed components go here -->
      
      <router-outlet></router-outlet>
<!-- Routed components go here -->
    

對於上面的配置,當這個應用的瀏覽器 URL 變為 /heroes 時,路由器就會把這個 URL 與路由路徑 /heroes 匹配,並把 HeroListComponent 作為兄弟元素顯示在宿主元件範本中的 RouterOutlet 下方。

Given the configuration above, when the browser URL for this application becomes /heroes, the router matches that URL to the route path /heroes and displays the HeroListComponent as a sibling element to the RouterOutlet that you've placed in the host component's template.

要想透過某些使用者操作(比如單擊一下 a 標籤)進行導航,請使用 RouterLink

To navigate as a result of some user action such as the click of an anchor tag, use RouterLink.

考慮下面的範本:

Consider the following template:

<h1>Angular Router</h1> <nav> <a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a> <a routerLink="/heroes" routerLinkActive="active">Heroes</a> </nav> <router-outlet></router-outlet>
src/app/app.component.html
      
      <h1>Angular Router</h1>
<nav>
  <a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
  <a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<router-outlet></router-outlet>
    

a 標籤上的 RouterLink 指令讓路由器可以控制這些元素。導航路徑是固定的,所以你可以給 routerLink 賦值一個字串(“一次性”繫結)。

The RouterLink directives on the anchor tags give the router control over those elements. The navigation paths are fixed, so you can assign a string to the routerLink (a "one-time" binding).

如果導航路徑更加動態,你可以給它繫結到一個範本表示式,該表示式要返回一個連結引數陣列。路由器會把該陣列解析成一個完整的 URL。

Had the navigation path been more dynamic, you could have bound to a template expression that returned an array of route link parameters; that is, the link parameters array. The router resolves that array into a complete URL.

RouterLinkActive 指令會根據當前的 RouterState 切換活動 RouterLink 上所繫結的 CSS 類別。

The RouterLinkActive directive toggles CSS classes for active RouterLink bindings based on the current RouterState.

在每個 a 標籤上,你會看到一個到 RouterLinkActive 指令的屬性繫結,就像 routerLinkActive="..."

On each anchor tag, you see a property binding to the RouterLinkActive directive that looks like routerLinkActive="...".

等號 = 右側的範本表示式,包含一個以空格分隔的 CSS 類別字串,當這個連結處於活動狀態時,路由器就會加上這些字串(並在非活動狀態時刪除)。你可以把 RouterLinkActive 指令設定成一串類別的字串,比如 [routerLinkActive]="'active fluffy'",也可以把它繫結到一個返回這樣一個字串的元件屬性上。

The template expression to the right of the equal sign, =, contains a space-delimited string of CSS classes that the Router adds when this link is active (and removes when the link is inactive). You set the RouterLinkActive directive to a string of classes such as [routerLinkActive]="'active fluffy'" or bind it to a component property that returns such a string.

活動路由連結會級聯到路由樹的每個級別,這樣父路由和子路由連結就可以同時處於活動狀態。要覆蓋這種行為,你可以用 { exact: true } 表示式繫結到 [routerLinkActiveOptions] 輸入繫結。使用 { exact: true } 之後,給定的 RouterLink 只有在 URL 與當前 URL 完全匹配時才會啟用。

Active route links cascade down through each level of the route tree, so parent and child router links can be active at the same time. To override this behavior, you can bind to the [routerLinkActiveOptions] input binding with the { exact: true } expression. By using { exact: true }, a given RouterLink will only be active if its URL is an exact match to the current URL.

路由器狀態

Router state

每個成功的導航生命週期結束後,路由器都會建構一個 ActivatedRoute 物件樹,它構成了路由器的當前狀態。你可以從任何地方使用應用的 Router 服務和 routerState 屬性來訪問當前的 RouterState

After the end of each successful navigation lifecycle, the router builds a tree of ActivatedRoute objects that make up the current state of the router. You can access the current RouterState from anywhere in the application using the Router service and the routerState property.

RouterState 中的每個 ActivatedRoute 都提供了向上或向下遍歷路由樹的方法,用於從父路由、子路由和兄弟路由中獲取資訊。

Each ActivatedRoute in the RouterState provides methods to traverse up and down the route tree to get information from parent, child and sibling routes.

啟用路由

Activated route

路由的路徑和引數可以透過注入名為 ActivatedRoute 的路由服務獲得。它提供了大量有用的資訊,包括:

The route path and parameters are available through an injected router service called the ActivatedRoute. It has a great deal of useful information including:

屬性

Property

說明

Description

url

一個路由路徑的 Observable,是一個由路由路徑的各個部分組成的字串陣列。

An Observable of the route path(s), represented as an array of strings for each part of the route path.

data

包含提供給當前路由的 data 物件的 Observable。 也包含任何由解析守衛解析出的值。

An Observable that contains the data object provided for the route. Also contains any resolved values from the resolve guard.

paramMap

一個包含該路由的必要引數和可選引數 mapObservable。 這個 map 支援從同一個引數中獲得單個或多個值。

An Observable that contains a map of the required and optional parameters specific to the route. The map supports retrieving single and multiple values from the same parameter.

queryParamMap

一個包含適用於所有路由的查詢引數 mapObservable。 這個 map 支援從同一個查詢引數中獲得單個或多個值。

An Observable that contains a map of the query parameters available to all routes. The map supports retrieving single and multiple values from the query parameter.

fragment

一個適用於所有路由的 URL 片段Observable

An Observable of the URL fragment available to all routes.

outlet

用來渲染該路由的 RouterOutlet 的名字。 對於無名出口,這個出口的名字是 primary

The name of the RouterOutlet used to render the route. For an unnamed outlet, the outlet name is primary.

routeConfig

包含原始路徑的那個路由的配置資訊。

The route configuration used for the route that contains the origin path.

parent

當該路由是子路由時,表示該路由的父級 ActivatedRoute

The route's parent ActivatedRoute when this route is a child route.

firstChild

包含該路由的子路由列表中的第一個 ActivatedRoute

Contains the first ActivatedRoute in the list of this route's child routes.

children

包含當前路由下所有啟用的子路由

Contains all the child routes activated under the current route.

還有兩個較舊的屬性,但更推薦使用它們的替代品,因為它們可能會在以後的 Angular 版本中棄用。

Two older properties are still available, however, their replacements are preferable as they may be deprecated in a future Angular version.

  • params :一個 Observable,它包含專屬於該路由的必要引數和可選引數。請改用 paramMap

    params: An Observable that contains the required and optional parameters specific to the route. Use paramMap instead.

  • queryParams:一個包含可用於所有路由的查詢引數Observable。請改用 queryParamMap

    queryParams: An Observable that contains the query parameters available to all routes. Use queryParamMap instead.

路由器事件

Router events

Router 在每次導航過程中都會透過 Router.events 屬性發出導航事件。這些事件的範圍貫穿從導航開始和結束之間的多個時間點。導航事件的完整列表如下表所示。

During each navigation, the Router emits navigation events through the Router.events property. These events range from when the navigation starts and ends to many points in between. The full list of navigation events is displayed in the table below.

路由事件

Router Event

說明

Description

NavigationStart

導航開始時觸發的事件

An event triggered when navigation starts.

RouteConfigLoadStart

Router 延遲載入路由配置之前觸發的事件

An event triggered before the Router lazy loads a route configuration.

RouteConfigLoadEnd

在某個路由已經延遲載入完畢時觸發的事件

An event triggered after a route has been lazy loaded.

RoutesRecognized

當路由器解析了 URL,而且路由已經識別完畢時觸發的事件

An event triggered when the Router parses the URL and the routes are recognized.

GuardsCheckStart

當路由器開始進入路由守衛階段時觸發的事件

An event triggered when the Router begins the Guards phase of routing.

ChildActivationStart

當路由器開始啟用某路由的子路由時觸發的事件

An event triggered when the Router begins activating a route's children.

ActivationStart

當路由器開始啟用某個路由時觸發的事件

An event triggered when the Router begins activating a route.

GuardsCheckEnd

當路由器成功結束了路由守衛階段時觸發的事件

An event triggered when the Router finishes the Guards phase of routing successfully.

ResolveStart

當路由器開始路由解析階段時觸發的事件

An event triggered when the Router begins the Resolve phase of routing.

ResolveEnd

當路由器的路由解析階段成功完成時觸發的事件

An event triggered when the Router finishes the Resolve phase of routing successfuly.

ChildActivationEnd

當路由器成功啟用某路由的子路由時觸發的事件

An event triggered when the Router finishes activating a route's children.

ActivationEnd

當路由器成功激活了某個路由時觸發的事件

An event triggered when the Router finishes activating a route.

NavigationEnd

當導航成功結束時觸發的事件

An event triggered when navigation ends successfully.

NavigationCancel

當導航被取消時觸發的事件。 這可能在導航期間某個路由守衛返回了 false 或返回了 UrlTree 以進行重新導向時發生。

An event triggered when navigation is canceled. This can happen when a Route Guard returns false during navigation, or redirects by returning a UrlTree.

NavigationError

當導航由於非預期的錯誤而失敗時觸發的事件

An event triggered when navigation fails due to an unexpected error.

Scroll

用來表示滾動的事件

An event that represents a scrolling event.

當啟用了 enableTracing 選項時,Angular 會把這些事件都記錄到控制檯。關於篩選路由器導航事件的範例,請參閱 Angular 中的 Observables 一章的路由器部分

When you enable the enableTracing option, Angular logs these events to the console. For an example of filtering router navigation events, see the router section of the Observables in Angular guide.

路由器術語

Router terminology

這裡是一些關鍵的 Router 術語及其含義:

Here are the key Router terms and their meanings:

路由器部件

Router Part

含義

Meaning

Router

為活動 URL 顯示應用中的元件。 管理從一個元件到另一個的導航。

Displays the application component for the active URL. Manages navigation from one component to the next.

RouterModule

一個單獨的 NgModule,它提供了一些必要的服務提供者和一些用於在應用檢視間導航的指令。

A separate NgModule that provides the necessary service providers and directives for navigating through application views.

Routes

定義一個路由陣列,每一個條目都會把一個 URL 路徑對映到元件。

Defines an array of Routes, each mapping a URL path to a component.

Route

定義路由器如何基於一個 URL 模式導航到某個元件。 大部分路由都由一個路徑和一個元件類別組成。

Defines how the router should navigate to a component based on a URL pattern. Most routes consist of a path and a component type.

RouterOutlet

該指令 (<router-outlet>) 用於指出路由器應該把檢視顯示在哪裡。

The directive (<router-outlet>) that marks where the router displays a view.

RouterLink

用於將可點選的 HTML 元素繫結到某個路由的指令。單擊帶有 routerLink 指令且繫結到字串連結引數陣列的元素,將觸發導航。

The directive for binding a clickable HTML element to a route. Clicking an element with a routerLink directive that is bound to a string or a link parameters array triggers a navigation.

RouterLinkActive

該指令會在元素上或元素內包含的相關 routerLink 處於活動/非活動狀態時,從 HTML 元素上新增/移除類別。

The directive for adding/removing classes from an HTML element when an associated routerLink contained on or inside the element becomes active/inactive.

ActivatedRoute

一個提供給每個路由元件的服務,其中包含當前路由專屬的資訊,例如路由引數、靜態資料、解析資料、全域性查詢引數和全域性片段。

A service that is provided to each route component that contains route specific information such as route parameters, static data, resolve data, global query params, and the global fragment.

RouterState

路由器的當前狀態,包括一棵當前啟用路由的樹以及遍歷這棵路由樹的便捷方法。

The current state of the router including a tree of the currently activated routes together with convenience methods for traversing the route tree.

連結引數陣列

Link parameters array

一個由路由器將其解釋為路由指南的陣列。你可以將該陣列繫結到 RouterLink 或將該陣列作為引數傳給 Router.navigate 方法。

An array that the router interprets as a routing instruction. You can bind that array to a RouterLink or pass the array as an argument to the Router.navigate method.

路由元件

Routing component

一個帶有 RouterOutlet 的 Angular 元件,可基於路由器的導航來顯示檢視。

An Angular component with a RouterOutlet that displays views based on router navigations.