# Routing # 路由 There are new requirements for the Tour of Heroes app: 有一些《英雄指南》的新需求: * Add a *Dashboard* view. 添加一个*仪表盘*视图。 * Add the ability to navigate between the *Heroes* and *Dashboard* views. 在*英雄列表*和*仪表盘*视图之间导航。 * When users click a hero name in either view, navigate to a detail view of the selected hero. 无论在哪个视图中点击一个英雄,都会导航到该英雄的详情页。 * When users click a *deep link* in an email, open the detail view for a particular hero. 在邮件中点击一个*深链接*,会直接打开一个特定英雄的详情视图。 When you’re done, users will be able to navigate the app like this: 完成时,用户就能像这样在应用中导航:
View navigations
## Add the `AppRoutingModule` ## 添加 `AppRoutingModule` In Angular, the best practice is to load and configure the router in a separate, top-level module that is dedicated to routing and imported by the root `AppModule`. 在 Angular 中,最好在一个独立的顶级模块中加载和配置路由器,它专注于路由功能,然后由根模块 `AppModule` 导入它。 By convention, the module class name is `AppRoutingModule` and it belongs in the `app-routing.module.ts` in the `src/app` folder. 按照惯例,这个模块类的名字叫做 `AppRoutingModule`,并且位于 `src/app` 下的 `app-routing.module.ts` 文件中。 Use the CLI to generate it. 使用 CLI 生成它。 ng generate module app-routing --flat --module=app
`--flat` puts the file in `src/app` instead of its own folder.
`--module=app` tells the CLI to register it in the `imports` array of the `AppModule`. `--flat` 把这个文件放进了 `src/app` 中,而不是单独的目录中。
`--module=app` 告诉 CLI 把它注册到 `AppModule` 的 `imports` 数组中。
The generated file looks like this: 生成的文件是这样的: You generally don't declare components in a routing module so you can delete the `@NgModule.declarations` array and delete `CommonModule` references too. 你通常不会在路由模块中声明组件,所以可以删除 `@NgModule.declarations` 并删除对 `CommonModule` 的引用。 You'll configure the router with `Routes` in the `RouterModule` so import those two symbols from the `@angular/router` library. 你将会使用 `RouterModule` 中的 `Routes` 类来配置路由器,所以还要从 `@angular/router` 库中导入这两个符号。 Add an `@NgModule.exports` array with `RouterModule` in it. Exporting `RouterModule` makes router directives available for use in the `AppModule` components that will need them. 添加一个 `@NgModule.exports` 数组,其中放上 `RouterModule` 。 导出 `RouterModule` 让路由器的相关指令可以在 `AppModule` 中的组件中使用。 `AppRoutingModule` looks like this now: 此刻的 `AppRoutingModule` 是这样的: ### Add routes ### 添加路由定义 *Routes* tell the router which view to display when a user clicks a link or pastes a URL into the browser address bar. *路由定义* 会告诉路由器,当用户点击某个链接或者在浏览器地址栏中输入某个 URL 时,要显示哪个视图。 A typical Angular `Route` has two properties: 典型的 Angular 路由(`Route`)有两个属性: 1. `path`: a string that matches the URL in the browser address bar. `path`:一个用于匹配浏览器地址栏中 URL 的字符串。 1. `component`: the component that the router should create when navigating to this route. `component`:当导航到此路由时,路由器应该创建哪个组件。 You intend to navigate to the `HeroesComponent` when the URL is something like `localhost:4200/heroes`. 如果你希望当 URL 为 `localhost:4200/heroes` 时,就导航到 `HeroesComponent`。 Import the `HeroesComponent` so you can reference it in a `Route`. Then define an array of routes with a single `route` to that component. 首先要导入 `HeroesComponent`,以便能在 `Route` 中引用它。 然后定义一个路由数组,其中的某个路由是指向这个组件的。 Once you've finished setting up, the router will match that URL to `path: 'heroes'` and display the `HeroesComponent`. 完成这些设置之后,路由器将会把 URL 匹配到 `path: 'heroes'`,并显示 `HeroesComponent`。 ### _RouterModule.forRoot()_ You first must initialize the router and start it listening for browser location changes. 你必须首先初始化路由器,并让它开始监听浏览器中的地址变化。 Add `RouterModule` to the `@NgModule.imports` array and configure it with the `routes` in one step by calling `RouterModule.forRoot()` _within_ the `imports` array, like this: 把 `RouterModule` 添加到 `@NgModule.imports` 数组中,并用 `routes` 来配置它。你只要调用 `imports` 数组中的 `RouterModule.forRoot()` 函数就行了。
The method is called `forRoot()` because you configure the router at the application's root level. The `forRoot()` method supplies the service providers and directives needed for routing, and performs the initial navigation based on the current browser URL. 这个方法之所以叫 `forRoot()`,是因为你要在应用的顶级配置这个路由器。 `forRoot()` 方法会提供路由所需的服务提供商和指令,还会基于浏览器的当前 URL 执行首次导航。
## Add _RouterOutlet_ ## 添加路由出口 (_RouterOutlet_) Open the `AppComponent` template replace the `` element with a `` element. 打开 `AppComponent` 的模板,把 `` 元素替换为 `` 元素。 You removed `` because you will only display the `HeroesComponent` when the user navigates to it. 之所以移除 ``,是因为只有当用户导航到这里时,才需要显示 `HeroesComponent`。 The `` tells the router where to display routed views. `` 会告诉路由器要在哪里显示路由到的视图。
The `RouterOutlet` is one of the router directives that became available to the `AppComponent` because `AppModule` imports `AppRoutingModule` which exported `RouterModule`. 能在 `AppComponent` 中使用 `RouterOutlet`,是因为 `AppModule` 导入了 `AppRoutingModule`,而 `AppRoutingModule` 中导出了 `RouterModule`。
#### Try it #### 试试看 You should still be running with this CLI command. 你的 CLI 命令应该仍在运行吧。 ng serve The browser should refresh and display the app title but not the list of heroes. 浏览器应该刷新,并显示着应用的标题,但是没有显示英雄列表。 Look at the browser's address bar. The URL ends in `/`. The route path to `HeroesComponent` is `/heroes`. 看看浏览器的地址栏。 URL 是以 `/` 结尾的。 而到 `HeroesComponent` 的路由路径是 `/heroes`。 Append `/heroes` to the URL in the browser address bar. You should see the familiar heroes master/detail view. 在地址栏中把 `/heroes` 追加到 URL 后面。你应该能看到熟悉的主从结构的英雄显示界面。 {@a routerlink} ## Add a navigation link (`routerLink`) ## 添加路由链接 (`routerLink`) Users shouldn't have to paste a route URL into the address bar. They should be able to click a link to navigate. 不应该让用户只能把路由的 URL 粘贴到地址栏中。他们还应该能通过点击链接进行导航。 Add a `