diff --git a/public/docs/ts/latest/tutorial/toh-pt5.jade b/public/docs/ts/latest/tutorial/toh-pt5.jade index fb63694e9a..9bc817ef99 100644 --- a/public/docs/ts/latest/tutorial/toh-pt5.jade +++ b/public/docs/ts/latest/tutorial/toh-pt5.jade @@ -2,47 +2,47 @@ include ../_util-fns :marked # Routing Around the App - + # 应用中的路由 - + We received new requirements for our Tour of Heroes application: - + 我们收到了一份《英雄指南》的新需求: - + * Add a *Dashboard* view. - + * 添加一个*仪表盘*视图。 - + * Navigate between the *Heroes* and *Dashboard* views. - + * 在*英雄列表*和*仪表盘*视图之间导航。 - + * Clicking on a hero in either view navigates to a detail view of the selected hero. - + * 无论在哪个视图中点击一个英雄,都会导航到该英雄的详情页。 - + * Clicking a *deep link* in an email opens the detail view for a particular hero; - + * 在邮件中点击一个*深链接*,会直接打开一个特定英雄的详情视图。 When we’re done, users will be able to navigate the app like this: - + 完成时,用户就能像这样浏览一个应用: - + figure.image-display img(src='/resources/images/devguide/toh/nav-diagram.png' alt="查看导航") :marked We'll add Angular’s *Component Router* to our app to satisfy these requirements. - + 我们将把Angular*组件路由器*加入应用中,以满足这些需求。(译注:硬件领域中的路由器是用来帮你找到另一台网络设备的,而这里的路由器用于帮你找到一个组件) - + .l-sub-section :marked The [Routing and Navigation](../guide/router.html) chapter covers the router in more detail than we will in this tutorial. - + [路由与导航](../guide/router.html)一章覆盖了比该教程中更详细的路由知识。 - + p Run the #[+liveExampleLink2('', 'toh-5')] for this part. p 运行这部分的#[+liveExampleLink2('在线例子', 'toh-5')]。 @@ -54,18 +54,18 @@ p 运行这部分的#[+liveExampleLink2('在线例子', 'toh-5')]。 pop out the preview window by clicking the blue 'X' button in the upper right corner: 注意看浏览器地址栏中的URL变化,点击右上角的蓝色'X'按钮,弹出预览窗口。 - + .l-main-section :marked ## Where We Left Off - + ## 我们在哪儿 - + Before we continue with our Tour of Heroes, let’s verify that we have the following structure after adding our hero service and hero detail component. If not, we’ll need to go back and follow the previous chapters. 在继续《英雄指南》之前,先来检查一下,在添加了英雄服务和英雄详情组件之后,你是否已经有了如下目录结构。如果没有,你得先回上一章,再照做一遍。 - + .filetree .file angular2-tour-of-heroes .children @@ -87,12 +87,12 @@ p 运行这部分的#[+liveExampleLink2('在线例子', 'toh-5')]。 .file typings.json :marked ### Keep the app transpiling and running - + ### 让应用代码保持转译和运行 - + Open a terminal/console window and enter the following command to start the TypeScript compiler, start the server, and watch for changes: - + 打开terminal/console窗口,运行下列命令启动TypeScript编译器,它会监视文件变更,并启动开发服务器: code-example(language="bash"). @@ -100,86 +100,86 @@ code-example(language="bash"). :marked The application runs and updates automatically as we continue to build the Tour of Heroes. - + 我们继续构建《英雄指南》,应用也会保持运行并自动更新。 ## Action plan - + ## 行动计划 - + Here's our plan: - + 下面是我们的计划: - + * Turn `AppComponent` into an application shell that only handles navigation - + * 把`AppComponent`变成应用程序的“壳”,它只处理导航, - + * Relocate the *Heroes* concerns within the current `AppComponent` to a separate `HeroesComponent` - + * 把现在由`AppComponent`关注的*英雄们*移到一个独立的`HeroesComponent`中, - + * Add routing - + * 添加路由 - + * Create a new `DashboardComponent` - + * 添加一个新的`DashboardComponent`组件 - + * Tie the *Dashboard* into the navigation structure - + * 把*仪表盘*加入导航结构中。 .l-sub-section :marked *Routing* is another name for *navigation*. The *router* is the mechanism for navigating from view to view. - + *路由*是导航的另一个名字。*路由器*就是从一个视图导航到另一个视图的机制。 - -.l-main-section + +.l-main-section :marked ## Splitting the *AppComponent* - + ## 拆分*AppComponent* - + Our current app loads `AppComponent` and immediately displays the list of heroes. - + 现在的应用会加载`AppComponent`组件,并且立刻显示出英雄列表。 - + Our revised app should present a shell with a choice of views (*Dashboard* and *Heroes*) and then default to one of them. - + 我们修改后的应用将提供一个壳,它会选择*仪表盘*和*英雄列表*视图之一,然后默认显示它。 The `AppComponent` should only handle navigation. Let's move the display of *Heroes* out of `AppComponent` and into its own `HeroesComponent`. - + `AppComponent`组件应该只处理导航。 我们来把*英雄列表*的显示职责,从`AppComponent`移到`HeroesComponent`组件中。 ### *HeroesComponent* - + `AppComponent` is already dedicated to *Heroes*. Instead of moving anything out of `AppComponent`, we'll just rename it `HeroesComponent` and create a new `AppComponent` shell separately. `AppComponent`的职责已经被移交给`HeroesComponent`了。 与其把`AppComponent`中所有的东西都搬过去,不如索性把它改名为`HeroesComponent`,然后单独创建一个新的`AppComponent`壳。 - + The steps are to rename: - + 改名的步骤如下: - + * `app.component.ts` file to `heroes.component.ts` - + * 把`app.component.ts`文件改名为`heroes.component.ts` - + * `AppComponent` class to `HeroesComponent` - + * 把`AppComponent`类改名为`HeroesComponent` - + * Selector `my-app` to `my-heroes` - + * 把`my-app`选择器改名为`my-heroes` :marked @@ -187,63 +187,63 @@ code-example(language="bash"). :marked ## Create *AppComponent* - + ## 创建*AppComponent* - + The new `AppComponent` will be the application shell. It will have some navigation links at the top and a display area below for the pages we navigate to. - + 新的`AppComponent`将成为应用的“壳”。 它将在顶部放一些导航链接,并且把我们要导航到的页面放在下面的显示区中。 - + The initial steps are: - + 这些起始步骤是: - + * create a new file named `app.component.ts`. - + * 创建一个名叫`app.component.ts`的新文件。 - + * define an `AppComponent` class. - + * 定义一个`AppComponent`类。 - + * `export` it so we can reference it during bootstrapping in `main.ts`. - + * `export`它,以便我们能在`main.ts`的启动期间引用它。 - + * expose an application `title` property. - + * 暴露应用的`title`属性。 - + * add the `@Component` metadata decorator above the class with a `my-app` selector. - + * 在类的上方添加`@Component`元数据装饰器,装饰器中带有`my-app`选择器。 - + * add a template with `

` tags surrounding a binding to the `title` property. - + * 在模板中添加一个`

`标签,包裹着到`title`属性的绑定。 - + * add the `` tags to the template so we still see the heroes. - + * 在模板中添加``标签,以便我们仍能看到英雄列表。 - + * add the `HeroesComponent` to the `directives` array so Angular recognizes the `` tags. - + * 添加`HeroesComponent`组件到`directives`数组中,以便Angular能认识``标签。 - + * add the `HeroService` to the `providers` array because we'll need it in every other view. - + * 添加`HeroService`到`providers`数组中,因为我们的每一个视图都需要它。 - + * add the supporting `import` statements. - + * 添加支持性的`import`语句。 - + Our first draft looks like this: - + 我们的第一个草稿就像这样: - + +makeExample('toh-5/ts/app/app.component.1.ts', null, 'app/app.component.ts (v1)') :marked .callout.is-critical @@ -253,11 +253,11 @@ code-example(language="bash"). Go back to the `HeroesComponent` and **remove the `HeroService`** from its `providers` array. We are *promoting* this service from the `HeroesComponent` to the `AppComponent`. We ***do not want two copies*** of this service at two different levels of our app. - + 回到`HeroesComponent`,并从`providers`数组中**移除`HeroService`**。 我们要把它从`HeroesComponent`*提升*到`AppComponent`中。 我们可不希望在应用的两个不同层次上存在它的***两个副本***。 - + :marked The app still runs and still displays heroes. Our refactoring of `AppComponent` into a new `AppComponent` and a `HeroesComponent` worked! @@ -266,59 +266,59 @@ code-example(language="bash"). 应用仍然在运行,并显示着英雄列表。 我们把`AppComponent`重构成了一个新的`AppComponent`和`HeroesComponent`,它们工作得很好! 我们毫发无损的完成了这次重构。 - + :marked ## Add Routing - + ## 添加路由 - - We're ready to take the next step. + + We're ready to take the next step. Instead of displaying heroes automatically, we'd like to show them *after* the user clicks a button. In other words, we'd like to navigate to the list of heroes. - + 我们已准备好开始下一步。 与其自动显示英雄列表,我们更希望在用户点击按钮之后才显示它。 换句话说,我们希望“导航”到英雄列表。 - + We'll need the Angular *Component Router*. 我们需要Angular的*组件路由器*。 - + ### Set the base tag - + ### 设置base标签 - - Open the `index.html` and add `` at the top of the `` section. - + + Open the `index.html` and add `` at the top of the `` section. + 打开`index.html`并且在``区的顶部添加``语句。 - + +makeExample('toh-5/ts/index.html', 'base-href', 'index.html (base href)')(format=".") .callout.is-important - + header base href is essential - + header base href是不可或缺的 - + :marked See the *base href* section of the [Router](../guide/router.html#!#base-href) chapter to learn why this matters. 查看[路由器](../guide/router-deprecated.html#!#base-href)一章的*base href*部分,了解为何如此。 - + :marked The Angular router is a combination of multiple provided services (`provideRouter`), multiple directives (`ROUTER_DIRECTIVES`), and a configuration (`RouterConfig`). We'll configure our routes first: - + Angular路由器是由多个服务(`ROUTER_PROVIDERS`)和多个指令(`ROUTER_DIRECTIVES`)以及一个配置装饰器(`RouteConfig`)组成的。我们一次性导入它们。 ### Configure and add the router - + ### 配置与添加路由器 Our application doesn't have a router yet. We'll create a configuration file for our routes that does two things (a) configure that router with *routes*. (b) provide an export to add the router to our bootstrap - + 我们的应用还没有路由器。我们得为这些路由创建一个配置文件,该文件要做两件事:(a) 使用*一些路由*配置路由器。(b) 提供一个导出,以便把该路由器添加到我们的启动代码。 *Routes* tell the router which views to display when a user clicks a link or @@ -327,134 +327,134 @@ code-example(language="bash"). *路由*告诉路由器,当用户点击链接或者把URL粘贴到浏览器地址栏时,应该显示哪个视图。 Let's define our first route, a route to the `HeroesComponent`. - + 我们来定义第一个路由 —— 到`HeroesComponent`的路由。 - + +makeExample('toh-5/ts/app/app.routes.2.ts', '', 'app/app.routes.ts')(format=".") :marked The `RouterConfig` is an array of *route definitions*. We have only one route definition at the moment but rest assured, we'll add more. - - + + 这个`RouteConfig`是一个*路由定义*的数组。 此刻我们只有一个路由定义,但别急,后面还会添加更多。 - + This *route definition* has three parts: - + “路由定义”包括三个部分: - + This *route definition* has two parts: * **path**: the router matches this route's path to the URL in the browser address bar (`/heroes`). - + * **path**: 路由器会用它来匹配路由中指定的路径和浏览器地址栏中的当前路径,如`/heroes`。 - + * **name**: the official name of the route; it *must* begin with a capital letter to avoid confusion with the *path* (`Heroes`). - + * **name**: 路由的正式名字,它*必须*以大写字母开头儿,以免和*path*混淆,如`Heroes`。 - + * **component**: the component that the router should create when navigating to this route (`HeroesComponent`). - + * **component**: 导航到此路由时,路由器需要创建的组件,如`HeroesComponent`。 .l-sub-section :marked Learn more about defining routes with RouterConfig in the [Routing](../guide/router.html) chapter. - + 要学习更多使用`RouterConfig`定义路由的知识,请参见[路由](../guide/router.html)一章。 :marked ### Make the router available. - + ### 让路由器生效 - + The *Component Router* is a service. We have to import our `APP_ROUTER_PROVIDERS` which contains our configured router and make it available to the application by adding it to the `bootstrap` array. - + *组件路由器*是一个服务。我们得导入`APP_ROUTER_PROVIDERS`(它包含了我们配置好的路由器),并通过把它添加到`bootstrap`的数组参数中让它在此应用中可用。 - + +makeExample('toh-5/ts/app/main.ts', '', 'app/main.ts')(format=".") :marked ### Router Outlet - + ### 路由插座(Outlet) If we paste the path, `/heroes`, into the browser address bar, the router should match it to the `'Heroes'` route and display the `HeroesComponent`. But where? - + 如果我们把路径`/heroes`粘贴到浏览器的地址栏,路由器会匹配到`'Heroes'`路由,并显示`HeroesComponent`组件。 但问题是,该把它显示在哪儿呢? - + We have to ***tell it where*** by adding `` marker tags to the bottom of the template. `RouterOutlet` is one of the `ROUTER_DIRECTIVES`. The router displays each component immediately below the `` as we navigate through the application. - + 我们必须***告诉它位置***,所以我们把``标签添加到模板的底部。 `RouterOutlet`是`ROUTER_DIRECTIVES`常量中的一员。 当我们在应用中导航时,路由器就把激活的组件显示在``里面。 - + ### Router Links - + ### 路由器链接 - + We don't really expect users to paste a route URL into the address bar. We add an anchor tag to the template which, when clicked, triggers navigation to the `HeroesComponent`. - + 我们当然不会真让用户往地址栏中粘贴路由的URL,而应该在模板中的什么地方添加一个a链接标签。点击时,就会导航到`HeroesComponent`组件。 - + The revised template looks like this: - + 修改过的模板是这样的: - + +makeExample('toh-5/ts/app/app.component.2.ts', 'template', 'app/app.component.ts (template v1)')(format=".") :marked Notice the `[routerLink]` binding in the anchor tag. We bind the `RouterLink` directive (another of the `ROUTER_DIRECTIVES`) to an array that tells the router where to navigate when the user clicks the link. - + 注意,a标签中的`[routerLink]`绑定。我们把`RouterLink`指令(`ROUTER_DIRECTIVES`中的另一个指令)绑定到一个数组。它将告诉路由器,当用户点击这个链接时,应该导航到哪里。 - + We define a *routing instruction* with a *link parameters array*. The array only has one element in our little sample, the quoted ***path* of the route** to follow. Looking back at the route configuration, we confirm that `'/heroes'` is the path of the route to the `HeroesComponent`. - + 我们通过一个*链接参数数组*定义了一个*路由说明*。 在这个小例子中,该数组只有一个元素,一个放在引号中的**路径**,作为路标。 回来看路由配置表,我们清楚的看到,这个路径 —— `'/heroes'`就是指向`HeroesComponent`的那个路由的路径。 - + .l-sub-section :marked Learn about the *link parameters array* in the [Routing](../guide/router.html#link-parameters-array) chapter. - + 学习关于 *链接参数数组* 的更多知识,参见[路由](../guide/router.html#link-parameters-array)一章。 - + :marked - Refresh the browser. We see only the app title. We don't see the heroes list. - + Refresh the browser. We see only the app title. We don't see the heroes list. + 刷新浏览器。我们只看到了应用标题。英雄列表到哪里去了? - + .l-sub-section :marked The browser's address bar shows `/`. The route path to `HeroesComponent` is `/heroes`, not `/`. We don't have a route that matches the path `/`, so there is nothing to show. That's something we'll want to fix. - + 浏览器的地址栏显示的是`/`。而到`HeroesComponent`的路由中的路径是`/heroes`,不是`/`。 我们没有任何路由能匹配当前的路径`/`,所以,自然没啥可显示的。 接下来,我们就修复这个问题。 - + :marked We click the "Heroes" navigation link, the browser bar updates to `/heroes`, and now we see the list of heroes. We are navigating at last! - + 我们点击“英雄列表(Heroes)”导航链接,浏览器地址栏更新为`/heroes`,并且看到了英雄列表。我们终于导航过去了! At this stage, our `AppComponent` looks like this. - + 在这个阶段,`AppComponent`看起来是这样的: - + +makeExample('toh-5/ts/app/app.component.2.ts',null, 'app/app.component.ts (v2)') :marked The *AppComponent* is now attached to a router and displaying routed views. @@ -466,39 +466,39 @@ code-example(language="bash"). :marked ## Add a *Dashboard* - + ## 添加一个*仪表盘* - + Routing only makes sense when we have multiple views. We need another view. - + 当我们有多个视图的时候,路由才有意义。所以我们需要另一个视图。 - + Create a placeholder `DashboardComponent` that gives us something to navigate to and from. - + 先创建一个`DashboardComponent`的占位符,让我们可以导航到它或从它导航出来。 - + +makeExample('toh-5/ts/app/dashboard.component.1.ts',null, 'app/dashboard.component.ts (v1)')(format=".") :marked We’ll come back and make it more useful later. - + 我们先不实现它,稍后,我们再回来,给这个组件一些实际用途。 ### Configure the dashboard route - + ### 配置仪表盘路由 - + Go back to `app.routes.ts` and teach it to navigate to the dashboard. - + 回到`app.routes.ts`文件,我们得教它如何导航到这个仪表盘。 - - Import the `DashboardComponent` so we can reference it in the dashboard route definition. - + + Import the `DashboardComponent` so we can reference it in the dashboard route definition. + 先导入`DashboardComponent`类,这样我们就可以在仪表盘的路由定义中引用它了。 - + Add the following `'Dashboard'` route definition to the `RouterConfig` array of definitions. - + 然后把下列`'Dashboard'`路由的定义添加到`@RouteConfig`数组中。 - + +makeExample('toh-5/ts/app/app.routes.1.ts','dashboard-route', 'app/app.routes.ts (Dashboard route)')(format=".") .l-sub-section @@ -507,24 +507,24 @@ code-example(language="bash"). We want the app to show the dashboard when it starts and we want to see a nice URL in the browser address bar that says `/dashboard`. - Remember that the browser launches with `/` in the address bar. + Remember that the browser launches with `/` in the address bar. We can use a redirect route to make this happen. - + 我们希望在应用启动的时候就显示仪表盘,而且我们希望在浏览器的地址栏看到一个好看的URL,比如`/dashboard`。 记住,浏览器启动时,在地址栏中使用的路径是`/`。 我们可以使用一个重定向路由来达到目的。 - + +makeExample('toh-5/ts/app/app.routes.1.ts','redirect-route', 'app/app.routes.ts (Redirect route)')(format=".") - + .l-sub-section :marked Learn about the *redirects* in the [Routing](../guide/router.html#!#redirect) chapter. - + 要学习关于*重定向*的更多知识,参见[路由与导航](../guide/router.html#!#redirect)一章。 :marked Finally, add a dashboard navigation link to the template, just above the *Heroes* link. - + 最后,在模板上添加一个到仪表盘的导航链接,就放在*英雄(Heroes)*链接的上方。 +makeExample('toh-5/ts/app/app.component.ts','template', 'app/app.component.ts (template)')(format=".") @@ -532,10 +532,10 @@ code-example(language="bash"). :marked We nestled the two links within `