fix: toh-p5 and p6.
This commit is contained in:
parent
b73cb2e1a1
commit
e1d5af61d2
|
@ -325,7 +325,7 @@ block angular-router
|
|||
和一套配置(`Routes`)。我们将先配置路由。
|
||||
|
||||
:marked
|
||||
### Set the base tag
|
||||
### Add the base tag
|
||||
|
||||
### 设置base标签
|
||||
|
||||
|
@ -400,12 +400,12 @@ block router-config-intro
|
|||
|
||||
+ifDocsFor('ts|js')
|
||||
:marked
|
||||
We'll export the `routing` constant using the **RouterModule.forRoot** method with our array of routes.
|
||||
This returns a configured router module we'll add to our root NgModule, `AppModule`.
|
||||
We'll export a `routing` constant initialized using the `RouterModule.forRoot` method applied to our !{_array} of routes.
|
||||
This method returns a **configured router module** that we'll add to our root NgModule, `AppModule`.
|
||||
|
||||
使用**RouterModule.forRoot**方法,导出包含了路由数组的`routing`常量。它返回一个配置好的路由模块,它将被加入到根NgModule - `AppModule`中。
|
||||
使用`RouterModule.forRoot`方法,导出包含了路由数组的`routing`常量。它返回一个**配置好的路由模块**,它将被加入到根NgModule - `AppModule`中。
|
||||
|
||||
+makeExcerpt('app/app.routing.1.ts (excerpt)', 'routing-export')
|
||||
+makeExcerpt('app/app.routing.1.ts (excerpt)', 'routing-export')
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
|
@ -420,7 +420,7 @@ block router-config-intro
|
|||
|
||||
### 让路由器生效
|
||||
|
||||
We've setup our initial routes in our `app.routing.ts` file. Now we'll add it to our root NgModule.
|
||||
We've setup initial routes in the `app.routing.ts` file. Now we'll add it to our root NgModule.
|
||||
|
||||
我们已经在`app.routing.ts`文件中设置好了初始路由,接着把它加到根模块(NgModule)中。
|
||||
|
||||
|
@ -443,12 +443,12 @@ block router-config-intro
|
|||
如果我们把路径`/heroes`粘贴到浏览器的地址栏,路由器会匹配到`'Heroes'`路由,并显示`HeroesComponent`组件。
|
||||
但问题是,该把它显示在哪儿呢?
|
||||
|
||||
We have to ***tell it where*** by adding `<router-outlet>` marker tags to the bottom of the template.
|
||||
`RouterOutlet` is one of the directives provided by the `RouterModule`.
|
||||
We have to ***tell it where*** by adding a `<router-outlet>` element to the bottom of the template.
|
||||
`RouterOutlet` is one of the <span if-docs="ts">directives provided by</span> the `!{_RouterModuleVsRouterDirectives}`.
|
||||
The router displays each component immediately below the `<router-outlet>` as we navigate through the application.
|
||||
|
||||
我们必须***告诉它位置***,所以我们把`<router-outlet>`标签添加到模板的底部。
|
||||
`RouterOutlet`是`ROUTER_DIRECTIVES`常量中的一员。
|
||||
`RouterOutlet`是`!{_RouterModuleVsRouterDirectives}`提供的<span if-docs="ts">指令之一</span>`。
|
||||
当我们在应用中导航时,路由器就把激活的组件显示在`<router-outlet>`里面。
|
||||
|
||||
### Router Links
|
||||
|
@ -464,30 +464,33 @@ block router-config-intro
|
|||
|
||||
修改过的模板是这样的:
|
||||
|
||||
+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 `RouterModule` directives) to a string
|
||||
that tells the router where to navigate when the user clicks the link.
|
||||
+makeExcerpt('app/app.component.1.ts', 'template-v2')
|
||||
|
||||
注意,a标签中的`[routerLink]`绑定。我们把`RouterLink`指令(`ROUTER_DIRECTIVES`中的另一个指令)绑定到一个数组。它将告诉路由器,当用户点击这个链接时,应该导航到哪里。
|
||||
|
||||
Since our link is not dynamic, we define a *routing instruction* with a **one-time binding** to our route **path**.
|
||||
Looking back at the route configuration, we confirm that `'/heroes'` is the path of the route to the `HeroesComponent`.
|
||||
|
||||
由于这个链接不是动态的,我们只要用**一次性绑定**的方式绑定到路由的路径(path)就行了。
|
||||
回来看路由配置表,我们清楚的看到,这个路径 —— `'/heroes'`就是指向`HeroesComponent`的那个路由的路径。
|
||||
|
||||
.l-sub-section
|
||||
block routerLink
|
||||
:marked
|
||||
For more dynamic router links, learn about the *link parameters array* in the [Routing](../guide/router.html#link-parameters-array) chapter.
|
||||
Notice the `routerLink` binding in the anchor tag.
|
||||
We bind the `RouterLink` directive (another of the `RouterModule` directives) to a string
|
||||
that tells the router where to navigate when the user clicks the link.
|
||||
|
||||
注意,a标签中的`[routerLink]`绑定。我们把`RouterLink`指令(`ROUTER_DIRECTIVES`中的另一个指令)绑定到一个数组。它将告诉路由器,当用户点击这个链接时,应该导航到哪里。
|
||||
|
||||
Since our link is not dynamic, we define a *routing instruction* with a **one-time binding** to our route **path**.
|
||||
Looking back at the route configuration, we confirm that `'/heroes'` is the path of the route to the `HeroesComponent`.
|
||||
|
||||
由于这个链接不是动态的,我们只要用**一次性绑定**的方式绑定到路由的路径(path)就行了。
|
||||
回来看路由配置表,我们清楚的看到,这个路径 —— `'/heroes'`就是指向`HeroesComponent`的那个路由的路径。
|
||||
|
||||
如果要用动态路由器链接,参阅[路由](../guide/router.html#link-parameters-array)中的*链接参数数组*一节。
|
||||
.l-sub-section
|
||||
:marked
|
||||
Learn more about dynamic router links and 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 and heroes link. We don't see the heroes list.
|
||||
|
||||
刷新浏览器。我们只看到了应用标题。英雄列表到哪里去了?
|
||||
刷新浏览器。我们只看到了应用标题和英雄链接。英雄列表到哪里去了?
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
|
@ -510,7 +513,7 @@ block router-config-intro
|
|||
|
||||
在这个阶段,`AppComponent`看起来是这样的:
|
||||
|
||||
+makeExample('toh-5/ts/app/app.component.2.ts',null, 'app/app.component.ts (v2)')
|
||||
+makeExample('app/app.component.1.ts', 'v2', 'app/app.component.ts (v2)')
|
||||
:marked
|
||||
The *AppComponent* is now attached to a router and displaying routed views.
|
||||
For this reason and to distinguish it from other kinds of components,
|
||||
|
@ -532,7 +535,7 @@ block router-config-intro
|
|||
|
||||
先创建一个`DashboardComponent`的占位符,让我们可以导航到它或从它导航出来。
|
||||
|
||||
+makeExample('toh-5/ts/app/dashboard.component.1.ts',null, 'app/dashboard.component.ts (v1)')(format=".")
|
||||
+makeExcerpt('app/dashboard.component.1.ts (v1)', '')
|
||||
:marked
|
||||
We’ll come back and make it more useful later.
|
||||
|
||||
|
@ -542,42 +545,47 @@ block router-config-intro
|
|||
|
||||
### 配置仪表盘路由
|
||||
|
||||
Go back to `app.routing.ts` and teach it to navigate to the dashboard.
|
||||
Go back to `!{_appRoutingTsVsAppComp}` and teach it to navigate to the dashboard.
|
||||
|
||||
回到`app.routing.ts`文件,我们得教它如何导航到这个仪表盘。
|
||||
回到`!{_appRoutingTsVsAppComp}`,我们得教它如何导航到这个仪表盘。
|
||||
|
||||
Import the `DashboardComponent` so we can reference it in the dashboard route definition.
|
||||
Import the dashboard component and
|
||||
add the following route definition to the `!{_RoutesVsAtRouteConfig}` !{_array} of definitions.
|
||||
|
||||
先导入`DashboardComponent`类,这样我们就可以在仪表盘的路由定义中引用它了。
|
||||
先导入`DashboardComponent`类,然后把下列路由的定义添加到`!{_RoutesVsAtRouteConfig}`数组中。
|
||||
|
||||
Add the following `'Dashboard'` route definition to the `Routes` array of definitions.
|
||||
- var _file = _docsFor == 'dart' ? 'lib/app_component.dart' : 'app/app.routing.ts'
|
||||
+makeExcerpt(_file + ' (Dashboard route)', 'dashboard')
|
||||
|
||||
然后把下列`'Dashboard'`路由的定义添加到`Routes`数组中。
|
||||
|
||||
+makeExample('toh-5/ts/app/app.routing.2.ts','dashboard-route', 'app/app.routing.ts (Dashboard route)')(format=".")
|
||||
|
||||
:marked
|
||||
We also need to add the `DashboardComponent` to our root NgModule's `declarations`.
|
||||
|
||||
我们还得把`DashboardComponent`添加到根模块的`declarations`数组中。
|
||||
+ifDocsFor('ts|js')
|
||||
:marked
|
||||
Also import and add `DashboardComponent` to our root NgModule's `declarations`.
|
||||
|
||||
还得把`DashboardComponent`添加到根模块的`declarations`数组中。
|
||||
|
||||
+makeExcerpt('app/app.module.ts', 'dashboard')
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
**Redirect**
|
||||
|
||||
**重定向**
|
||||
:marked
|
||||
#### !{_redirectTo}
|
||||
|
||||
#### !{_redirectTo}
|
||||
|
||||
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.
|
||||
|
||||
我们希望在应用启动的时候就显示仪表盘,而且我们希望在浏览器的地址栏看到一个好看的URL,比如`/dashboard`。
|
||||
记住,浏览器启动时,在地址栏中使用的路径是`/`。
|
||||
我们可以使用一个重定向路由来达到目的。
|
||||
|
||||
+makeExample('toh-5/ts/app/app.routing.2.ts','redirect-route', 'app/app.routing.ts (Redirect route)')(format=".")
|
||||
我们希望在应用启动的时候就显示仪表盘,而且我们希望在浏览器的地址栏看到一个好看的URL,比如`/dashboard`。
|
||||
记住,浏览器启动时,在地址栏中使用的路径是`/`。
|
||||
我们可以使用一个重定向路由来达到目的。
|
||||
|
||||
block redirect-vs-use-as-default
|
||||
:marked
|
||||
We can use a redirect route to make this happen. Add the following
|
||||
to our array of route definitions:
|
||||
|
||||
可以使用重定向路由来实现它。添加下面的内容到路由定义的数组中:
|
||||
|
||||
+makeExcerpt('app/app.routing.ts','redirect')
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
|
@ -587,10 +595,15 @@ block router-config-intro
|
|||
|
||||
:marked
|
||||
#### Add navigation to the template
|
||||
|
||||
#### 添加导航到模版中
|
||||
|
||||
Finally, add a dashboard navigation link to the template, just above the *Heroes* link.
|
||||
|
||||
最后,在模板上添加一个到仪表盘的导航链接,就放在*英雄(Heroes)*链接的上方。
|
||||
|
||||
- var _vers = _docsFor == 'dart' ? '' : '.1'
|
||||
+makeExcerpt('app/app.component' + _vers + '.ts', 'template-v3')
|
||||
|
||||
+makeExample('toh-5/ts/app/app.component.3.ts','template', 'app/app.component.ts (template)')(format=".")
|
||||
.l-sub-section
|
||||
|
@ -617,24 +630,27 @@ block router-config-intro
|
|||
|
||||
把元数据中的`template`属性替换为`templateUrl`属性,它将指向一个新的模板文件。
|
||||
|
||||
+makeExample('toh-5/ts/app/dashboard.component.ts', 'template-url', 'app/dashboard.component.ts (templateUrl)')(format=".")
|
||||
+makeExcerpt('app/dashboard.component.ts', 'templateUrl')
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
We specify the path _all the way back to the application root_ — `app/` in this case —
|
||||
because Angular doesn't support relative paths _by default_.
|
||||
We _can_ switch to [component-relative paths](../cookbook/component-relative-paths.html) if we prefer.
|
||||
block templateUrl-path-resolution
|
||||
:marked
|
||||
We specify the path _all the way back to the application root_ —
|
||||
<span if-docs="ts">`app/` in this case —</span>
|
||||
because Angular doesn't support relative paths _by default_.
|
||||
We _can_ switch to [component-relative paths](../cookbook/component-relative-paths.html) if we prefer.
|
||||
|
||||
我们指定的所有路径_都是相对于该应用的根目录(这里是`app/`)的_。
|
||||
因为Angular_默认_不支持使用相对于当前模块的路径。
|
||||
只要喜欢,我们也_可以_切换成[相对于组件的路径](../cookbook/component-relative-paths.html)模式。
|
||||
我们指定的所有路径_都是相对于该应用的根目录 - <span if-docs="ts">这里是`app/`</span>。
|
||||
因为Angular_默认_不支持使用相对于当前模块的路径。
|
||||
只要喜欢,我们也_可以_切换成[相对于组件的路径](../cookbook/component-relative-paths.html)模式。
|
||||
|
||||
:marked
|
||||
Create that file with these contents:
|
||||
Create that file with this content:
|
||||
|
||||
使用下列内容创建文件:
|
||||
|
||||
+makeExample('toh-5/ts/app/dashboard.component.html', null, 'app/dashboard.component.html')(format=".")
|
||||
+makeExcerpt('app/dashboard.component.html')
|
||||
|
||||
:marked
|
||||
We use `*ngFor` once again to iterate over a list of heroes and display their names.
|
||||
We added extra `<div>` elements to help with styling later in this chapter.
|
||||
|
@ -653,14 +669,14 @@ block router-config-intro
|
|||
|
||||
### 共享*HeroService*
|
||||
|
||||
We'd like to re-use the `HeroService` to populate the component's `heroes` array.
|
||||
We'd like to re-use the `HeroService` to populate the component's `heroes` !{_array}.
|
||||
|
||||
我们想要复用`HeroService`来存放组件的`heroes`数组。
|
||||
|
||||
Recall earlier in the chapter that we removed the `HeroService` from the `providers` array of the `HeroesComponent`
|
||||
and added it to the `providers` array of the root `NgModule`.
|
||||
Recall earlier in the chapter that we removed the `HeroService` from the `providers` !{_array} of `HeroesComponent`
|
||||
and added it to the `providers` !{_array} of `!{_AppModuleVsAppComp}`.
|
||||
|
||||
回忆一下,在前面的章节中,我们从`HeroesComponent`的`providers`数组中移除了`HeroService`服务,并把它添加到顶级组件`AppComponent`的`providers`数组中。
|
||||
回忆一下,在前面的章节中,我们从`HeroesComponent`的`providers`数组中移除了`HeroService`服务,并把它添加到顶级组件`!{_AppModuleVsAppComp}`的`providers`数组中。
|
||||
|
||||
That move created a singleton `HeroService` instance, available to *all* components of the application.
|
||||
Angular will inject `HeroService` and we'll use it here in the `DashboardComponent`.
|
||||
|
@ -672,11 +688,12 @@ block router-config-intro
|
|||
|
||||
### 获取英雄数组
|
||||
|
||||
Open the `dashboard.component.ts` and add the requisite `import` statements.
|
||||
Open <span ngio-ex>dashboard.component.ts</span> and add the requisite `import` statements.
|
||||
|
||||
打开`dashboard.component.ts`文件,并把必备的`import`语句加进去。
|
||||
打开<span ngio-ex>dashboard.component.ts</span>文件,并把必备的`import`语句加进去。
|
||||
|
||||
+makeExcerpt('app/dashboard.component.2.ts','imports')
|
||||
|
||||
+makeExample('toh-5/ts/app/dashboard.component.2.ts','imports', 'app/dashboard.component.ts (导入)')(format=".")
|
||||
:marked
|
||||
We need `OnInit` interface because we'll initialize the heroes in the `ngOnInit` method as we've done before.
|
||||
We need the `Hero` and `HeroService` symbols in order to reference those types.
|
||||
|
@ -688,29 +705,29 @@ block router-config-intro
|
|||
|
||||
我们现在就实现`DashboardComponent`类,像这样:
|
||||
|
||||
+makeExample('toh-5/ts/app/dashboard.component.2.ts','component', 'app/dashboard.component.ts (class)')
|
||||
+makeExcerpt('app/dashboard.component.2.ts (class)', 'component')
|
||||
|
||||
:marked
|
||||
We saw this kind of logic before in the `HeroesComponent`.
|
||||
We've seen this kind of logic before in the `HeroesComponent`:
|
||||
|
||||
在`HeroesComponent`之前,我们也看到过类似的逻辑:
|
||||
|
||||
* create a `heroes` array property
|
||||
* Define a `heroes` !{_array} property.
|
||||
|
||||
* 创建一个`heroes`数组属性
|
||||
|
||||
* inject the `HeroService` in the constructor and hold it in a private `heroService` field.
|
||||
* Inject the `HeroService` in the constructor and hold it in a private `!{_priv}heroService` field.
|
||||
|
||||
* 把`HeroService`注入构造函数中,并且把它保存在一个私有的`heroService`字段中。
|
||||
* 把`HeroService`注入构造函数中,并且把它保存在一个私有的`!{_priv}heroService`字段中。
|
||||
|
||||
* call the service to get heroes inside the Angular `ngOnInit` lifecycle hook.
|
||||
* Call the service to get heroes inside the Angular `ngOnInit` lifecycle hook.
|
||||
|
||||
* 在Angular的`ngOnInit`生命周期钩子里面调用服务来获得英雄列表。
|
||||
|
||||
The noteworthy differences: we cherry-pick four heroes (2nd, 3rd, 4th, and 5th) with *slice*
|
||||
The noteworthy differences: we cherry-pick four heroes (2nd, 3rd, 4th, and 5th)
|
||||
and stub the `gotoDetail` method until we're ready to implement it.
|
||||
|
||||
值得注意的区别是:我们用*slice*随机提取了四个英雄(第2、3、4、5个),暂时隔离`gotoDetail`方法直到时机成熟。
|
||||
值得注意的区别是:我们提取了四个英雄(第2、3、4、5个),暂时隔离`gotoDetail`方法直到时机成熟。
|
||||
|
||||
Refresh the browser and see four heroes in the new dashboard.
|
||||
|
||||
|
@ -739,17 +756,17 @@ block router-config-intro
|
|||
|
||||
1. 把一个指向该英雄的“深链接”URL粘贴到浏览器的地址栏。
|
||||
|
||||
Adding a `'HeroDetail'` route seem an obvious place to start.
|
||||
Adding a hero-detail route seems like an obvious place to start.
|
||||
|
||||
添加`'HeroDetail'`路由,是一个显而易见的起点。
|
||||
添加`hero-detail`路由,是一个显而易见的起点。
|
||||
|
||||
### Routing to a hero detail
|
||||
|
||||
### 路由到一个英雄详情
|
||||
|
||||
We'll add a route to the `HeroDetailComponent` in the `app.routing.ts` where our other routes are configured.
|
||||
We'll add a route to the `HeroDetailComponent` in `!{_appRoutingTsVsAppComp}` where our other routes are configured.
|
||||
|
||||
我们将在`app.routing.ts`中添加一个到`HeroDetailComponent`的路由,也就是配置其它路由的地方。
|
||||
我们将在`!{_appRoutingTsVsAppComp}`中添加一个到`HeroDetailComponent`的路由,也就是配置其它路由的地方。
|
||||
|
||||
The new route is a bit unusual in that we must tell the `HeroDetailComponent` *which hero to show*.
|
||||
We didn't have to tell the `HeroesComponent` or the `DashboardComponent` anything.
|
||||
|
@ -757,11 +774,12 @@ block router-config-intro
|
|||
新路由的不寻常之处在于,我们必须告诉`HeroDetailComponent`*该显示哪个英雄*。
|
||||
以前的`HeroesComponent`组件和`DashboardComponent`组件还从未要求我们告诉它任何东西。
|
||||
|
||||
At the moment the parent `HeroesComponent` sets the component's `hero` property to a hero object with a binding like this.
|
||||
At the moment the parent `HeroesComponent` sets the component's `hero` property to a
|
||||
hero object with a binding like this.
|
||||
|
||||
现在,父组件`HeroesComponent`通过数据绑定来把一个英雄对象设置为组件的`hero`属性。就像这样:
|
||||
|
||||
code-example(format='').
|
||||
code-example(language="html").
|
||||
<my-hero-detail [hero]="selectedHero"></my-hero-detail>
|
||||
|
||||
:marked
|
||||
|
@ -775,7 +793,8 @@ code-example(format='').
|
|||
|
||||
### 参数化路由
|
||||
|
||||
We *can* add the hero's `id` to the URL. When routing to the hero whose `id` is 11, we could expect to see an URL such as this:
|
||||
We *can* add the hero's `id` to the URL. When routing to the hero whose `id` is 11,
|
||||
we could expect to see an URL such as this:
|
||||
|
||||
我们*可以*把英雄的`id`添加到URL中。当导航到一个`id`为11的英雄时,我们期望的URL是这样的:
|
||||
|
||||
|
@ -797,7 +816,8 @@ code-example(format='').
|
|||
|
||||
下面是我们将使用的*路由定义*。
|
||||
|
||||
+makeExample('toh-5/ts/app/app.routing.2.ts','hero-detail-route', 'app/app.routing.ts (route to HeroDetailComponent)')(format=".")
|
||||
- var _file = _docsFor == 'dart' ? 'app/app.component.ts' : 'app/app.routing.ts'
|
||||
+makeExcerpt(_file + ' (hero detail)','hero-detail')
|
||||
|
||||
:marked
|
||||
The colon (:) in the path indicates that `:id` is a placeholder to be filled with a specific hero `id`
|
||||
|
@ -805,20 +825,13 @@ code-example(format='').
|
|||
|
||||
路径中的冒号(:)表示`:id`是一个占位符,当导航到这个`HeroDetailComponent`组件时,它将被填入一个特定英雄的`id`。
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
Of course we have to import the `HeroDetailComponent` before we create this route:
|
||||
|
||||
当然,在创建这个路由之前,我们必须导入`HeroDetailComponent`类:
|
||||
|
||||
+makeExample('toh-5/ts/app/app.routing.2.ts','hero-detail-import')(format=".")
|
||||
:marked
|
||||
Add the `HeroDetailComponent` to our root NgModule's `declarations`.
|
||||
|
||||
把`HeroDetailComponent`添加到根模块的`declarations`数组中。
|
||||
|
||||
+makeExample('toh-5/ts/app/app.module.3.ts','hero-detail-declaration', 'app/app.module.ts (Hero Detail declaration)')(format=".")
|
||||
|
||||
+ifDocsFor('dart')
|
||||
.l-sub-section
|
||||
:marked
|
||||
Remember to import the hero detail component before creating this route.
|
||||
|
||||
记得在创建这个路由前导入英雄详情组件。
|
||||
|
||||
:marked
|
||||
We're finished with the application routes.
|
||||
|
||||
|
@ -861,65 +874,57 @@ code-example(format='').
|
|||
|
||||
模板不用修改,我们会用原来的方式显示英雄。导致这次大修的原因是如何获得这个英雄的数据。
|
||||
|
||||
We will no longer receive the hero in a parent component property binding.
|
||||
The new `HeroDetailComponent` should take the `id` parameter from the `params` observable
|
||||
in the `ActivatedRoute` service and use the `HeroService` to fetch the hero with that `id`.
|
||||
|
||||
我们不会再从父组件的属性绑定中取得英雄数据。
|
||||
新的`HeroDetailComponent`应该从`ActivatedRoute`服务的可观察对象`params`中取得`id`参数,并通过`HeroService`服务获取具有这个指定`id`的英雄数据。
|
||||
|
||||
We need an import statement to reference the `ActivatedRoute` and `Params` types.
|
||||
|
||||
我们需要一个import语句,来引用`ActivatedRoute`和`Params`类型。
|
||||
|
||||
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-activated-route')(format=".")
|
||||
|
||||
block route-params
|
||||
:marked
|
||||
We will no longer receive the hero in a parent component property binding.
|
||||
The new `HeroDetailComponent` should take the `id` parameter from the `params` observable
|
||||
in the `ActivatedRoute` service and use the `HeroService` to fetch the hero with that `id`.
|
||||
|
||||
我们不会再从父组件的属性绑定中取得英雄数据。
|
||||
新的`HeroDetailComponent`应该从`ActivatedRoute`服务的可观察对象`params`中取得`id`参数,并通过`HeroService`服务获取具有这个指定`id`的英雄数据。
|
||||
|
||||
:marked
|
||||
We import the `HeroService`so we can fetch a hero.
|
||||
|
||||
我们导入了`HeroService`,现在就能获取一个英雄了。
|
||||
|
||||
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-hero-service')(format=".")
|
||||
First, add the requisite imports:
|
||||
|
||||
首先,添加需要的导入项目:
|
||||
|
||||
- var _vers = _docsFor == 'dart' ? '' : '.1'
|
||||
+makeExcerpt('app/hero-detail.component' + _vers + '.ts', 'added-imports', '')
|
||||
|
||||
- var _ActivatedRoute = _docsFor == 'dart' ? 'RouteParams' : 'ActivatedRoute'
|
||||
:marked
|
||||
We import the `OnInit` interface because we'll call the `HeroService` inside the `ngOnInit` component lifecycle hook.
|
||||
Let's have the `!{_ActivatedRoute}` service and the `HeroService` injected
|
||||
into the constructor, saving their values in private fields:
|
||||
|
||||
然后注入`!{_ActivatedRoute}`和`HeroService`服务到构造函数中,将他们的值保存到私有变量中:
|
||||
|
||||
我们得导入`OnInit`接口,因为我们需要在组件的`ngOnInit`生命周期钩子中调用`HeroService`。
|
||||
|
||||
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-oninit')(format=".")
|
||||
|
||||
:marked
|
||||
We inject the both the `ActivatedRoute` service and the `HeroService` into the constructor as we've done before,
|
||||
making private variables for both:
|
||||
|
||||
像以前一样,我们把`RouteParams`服务和`HeroService`服务注入到构造函数中,让它们成为私有变量。
|
||||
|
||||
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'ctor', 'app/hero-detail.component.ts (构造函数)')(format=".")
|
||||
+makeExcerpt('app/hero-detail.component.ts (constructor)', 'ctor')
|
||||
|
||||
:marked
|
||||
We tell the class that we want to implement the `OnInit` interface.
|
||||
|
||||
我们告诉这个类,我们要实现`OnInit`接口。
|
||||
|
||||
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'implement')(format=".")
|
||||
+makeExcerpt('app/hero-detail.component.ts', 'implement', '')(format=".")
|
||||
|
||||
:marked
|
||||
Inside the `ngOnInit` lifecycle hook, we use the `params` observable to
|
||||
extract the `id` parameter value from the `ActivateRoute` service
|
||||
and use the `HeroService` to fetch the hero with that `id`.
|
||||
block ngOnInit
|
||||
:marked
|
||||
Inside the `ngOnInit` lifecycle hook, we use the `params` observable to
|
||||
extract the `id` parameter value from the `ActivateRoute` service
|
||||
and use the `HeroService` to fetch the hero with that `id`.
|
||||
|
||||
在`ngOnInit`生命周期钩子中,从`RouteParams`服务中提取`id`参数,并且使用`HeroService`来获得具有这个`id`的英雄数据。
|
||||
在`ngOnInit`生命周期钩子中,从`RouteParams`服务中提取`id`参数,并且使用`HeroService`来获得具有这个`id`的英雄数据。
|
||||
|
||||
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'ng-oninit', 'app/hero-detail.component.ts (ngOnInit)')(format=".")
|
||||
+makeExcerpt('app/hero-detail.component.ts', 'ngOnInit')
|
||||
|
||||
:marked
|
||||
Notice how we extract the `id` by calling the `forEach` method
|
||||
which will deliver our array of route parameters.
|
||||
|
||||
注意我们提取`id`的方法:调用`forEach`方法,它会提供一个路由参数的数组。
|
||||
block extract-id
|
||||
:marked
|
||||
Notice how we extract the `id` by calling the `forEach` method
|
||||
which will deliver our !{_array} of route parameters.
|
||||
|
||||
注意我们提取`id`的方法:调用`forEach`方法,它会提供一个路由参数的数组。
|
||||
- var _str2int = _docsFor == 'dart' ? '<code>int.parse</code> static method' : 'JavaScript (+) operator'
|
||||
|
||||
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'get-id')(format=".")
|
||||
|
||||
:marked
|
||||
The hero `id` is a number. Route parameters are *always strings*.
|
||||
So we convert the route parameter value to a number with the !{_str2int}.
|
||||
|
@ -940,7 +945,7 @@ code-example(format='').
|
|||
|
||||
打开`HeroService`,并添加一个`getHero`方法,用来通过`id`从`getHeros`过滤英雄列表:
|
||||
|
||||
+makeExample('toh-5/ts/app/hero.service.ts', 'get-hero', 'app/hero.service.ts (getHero)')(format=".")
|
||||
+makeExcerpt('app/hero.service.ts', 'getHero')
|
||||
|
||||
:marked
|
||||
Let's return to the `HeroDetailComponent` to clean up loose ends.
|
||||
|
@ -963,39 +968,41 @@ code-example(format='').
|
|||
现在用户可以点击`AppComponent`中的两个链接,或点击浏览器的“后退”按钮。
|
||||
我们来添加第三个选项:一个`goBack`方法,来根据浏览器的历史堆栈,后退一步。
|
||||
|
||||
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'go-back', 'app/hero-detail.component.ts (goBack)')(format=".")
|
||||
+makeExcerpt('app/hero-detail.component.ts', 'goBack')
|
||||
|
||||
- var _CanDeactivateGuard = _docsFor == 'dart' ? '<em>routerCanDeactivate</em> hook' : '<em>CanDeactivate</em> guard'
|
||||
- var _CanDeactivateGuardUri = _docsFor == 'dart' ? 'angular2.router/CanDeactivate-class' : 'router/index/CanDeactivate-interface'
|
||||
.l-sub-section
|
||||
:marked
|
||||
Going back too far could take us out of the application.
|
||||
That's acceptable in a demo. We'd guard against it in a real application,
|
||||
perhaps with the [*CanDeactivate* guard](../api/router/index/CanDeactivate-interface.html).
|
||||
|
||||
回退太多步儿会跑出我们的应用。
|
||||
在Demo中,这算不上问题。但在真实的应用中,我们需要对此进行防范。
|
||||
也许你该用[*CanDeactivate*守卫](../api/router/index/CanDeactivate-interface.html).。
|
||||
:marked
|
||||
Going back too far could take us out of the application.
|
||||
That's acceptable in a demo. We'd guard against it in a real application,
|
||||
perhaps with the [!{_CanDeactivateGuard}](../api/!{_CanDeactivateGuardUri}.html).
|
||||
|
||||
回退太多步儿会跑出我们的应用。
|
||||
在Demo中,这算不上问题。但在真实的应用中,我们需要对此进行防范。
|
||||
也许你该用[!{_CanDeactivateGuard}](../api/!{_CanDeactivateGuardUri}.html).。
|
||||
|
||||
:marked
|
||||
Then we wire this method with an event binding to a *Back* button that we add to the bottom of the component template.
|
||||
|
||||
然后,我们通过一个事件绑定把此方法绑定到模板底部的*后退(Back)*按钮上。
|
||||
|
||||
+makeExample('toh-5/ts/app/hero-detail.component.html', 'back-button')(format=".")
|
||||
+makeExcerpt('app/hero-detail.component.html', 'back-button', '')
|
||||
|
||||
:marked
|
||||
Modifing the template to add this button spurs us to take one more incremental improvement and migrate the template to its own file
|
||||
called `hero-detail.component.html`
|
||||
called <span ngio-ex>hero-detail.component.html</span>
|
||||
|
||||
修改模板,添加这个按钮以提醒我们还要做更多的改进,并把模板移到独立的`hero-detail.component.html`文件中去。
|
||||
修改模板,添加这个按钮以提醒我们还要做更多的改进,并把模板移到独立的<span ngio-ex>hero-detail.component.html</span>文件中去。
|
||||
|
||||
+makeExample('toh-5/ts/app/hero-detail.component.html', '', 'app/hero-detail.component.html')(format=".")
|
||||
+makeExample('app/hero-detail.component.html')
|
||||
|
||||
:marked
|
||||
We update the component metadata with a `templateUrl` pointing to the template file that we just created.
|
||||
|
||||
然后更新组件的元数据,用一个`templateUrl`属性指向我们刚刚创建的模板文件。
|
||||
|
||||
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'template-url', 'app/hero-detail.component.ts (templateUrl)')(format=".")
|
||||
+makeExcerpt('app/hero-detail.component.ts', 'templateUrl')
|
||||
|
||||
:marked
|
||||
Here's the (nearly) finished `HeroDetailComponent`:
|
||||
|
@ -1030,37 +1037,45 @@ code-example(format='').
|
|||
当初我们重写`DashboardComponent`的时候,`gotoDetail`还是一个“桩方法”。
|
||||
现在,我们给它一个真正的实现。
|
||||
|
||||
+makeExample('toh-5/ts/app/dashboard.component.ts','goto-detail', 'app/dashboard.component.ts (gotoDetail)')(format=".")
|
||||
+makeExcerpt('app/dashboard.component.ts','gotoDetail')
|
||||
|
||||
:marked
|
||||
The `gotoDetail` method navigates in two steps:
|
||||
|
||||
`gotoDetail`方法分两步完成导航:
|
||||
|
||||
1. set a route *link parameters array*
|
||||
1. Set a route *link parameters !{_array}*
|
||||
|
||||
1. 生成路由的 *链接参数数组*
|
||||
|
||||
1. pass the array to the router's navigate method.
|
||||
1. Pass the !{_array} to the router's navigate method
|
||||
|
||||
1. 把这个数组传给路由器的navigate方法。
|
||||
|
||||
We wrote *link parameters arrays* in the `AppComponent` for the navigation links.
|
||||
Those arrays had only one element, the path of the destination route.
|
||||
For navigation, we wrote router links <span if-docs="dart">as *link
|
||||
parameters !{_array}s*</span> in the [`AppComponent`
|
||||
template](#router-links). Those link<span if-docs="dart"> parameters
|
||||
!{_array}</span>s had only one element, the !{_pathVsName} of the
|
||||
destination route.
|
||||
|
||||
我们当初在`AppComponent`中生成导航链接的时候曾写过*链接参数数组*。
|
||||
那些数组中只有一个元素:目标路由的路径。
|
||||
我们为导航在[`AppComponent`的模板](#router-links)中生成导航链接<span if-docs="dart">as *link
|
||||
parameters !{_array}s*</span>。这些链接<span if-docs="dart"> parameters
|
||||
!{_array}</span>只有一个元素:目标路由的路径。
|
||||
|
||||
This link parameters !{_array} has two elements, the ***!{_pathVsName}*** of
|
||||
the destination route and a ***route parameter*** <span if-docs="dart">with
|
||||
an `id` field</span> set to the value of the selected hero's `id`.
|
||||
|
||||
这个链接参数数组有两个元素:目标路由的***路径(path)***和一个***路由参数对象***,其中包括一个`id`字段,它的取值是所选英雄的`id`。
|
||||
|
||||
The two !{_array} items align with the ***!{_pathVsName}*** and ***:id***
|
||||
token in the parameterized hero detail route definition we added to
|
||||
`!{_appRoutingTsVsAppComp}` earlier in the chapter:
|
||||
|
||||
This array has two elements, the ***path*** of the destination route and a ***route parameter***
|
||||
with an `id` field set to the value of the selected hero's `id`.
|
||||
这两个数组项目与我们之前在`!{_appRoutingTsVsAppComp}`中添加的***path***和***:id***为代号被参数化的英雄详情路由的配置对象对应。
|
||||
|
||||
这个数组则两个元素,目标路由的***路径(path)***,和一个***路由参数对象***,其中包括一个`id`字段,它的取值是所选英雄的`id`。
|
||||
|
||||
The two array items align with the ***path*** and ***:id*** token in the parameterized `HeroDetail` route configuration we added to `app.routing.ts` earlier in the chapter.
|
||||
|
||||
当初我们在`app.routing.ts`中添加路由的时候,这两个数组元素以***path***和***:id***为代号被参数化的`HeroDetail`路由配置对象中。
|
||||
|
||||
+makeExample('toh-5/ts/app/app.routing.2.ts','hero-detail-route', 'app/app.routing.ts (hero detail route)')(format=".")
|
||||
- var _file = _docsFor == 'dart' ? 'app/app.component.ts' : 'app/app.routing.ts'
|
||||
+makeExcerpt(_file + ' (hero detail)', 'hero-detail')
|
||||
|
||||
:marked
|
||||
The `DashboardComponent` doesn't have the router yet. We obtain it in the usual way:
|
||||
|
@ -1069,9 +1084,9 @@ code-example(format='').
|
|||
`DashboardComponent`还没有路由器。我们使用常规的方式为它加上路由:
|
||||
`import` `router`对象的引用,并且把它注入到构造函数中(就像`HeroService`那样):
|
||||
|
||||
+makeExample('toh-5/ts/app/dashboard.component.ts','import-router', 'app/dashboard.component.ts (节选)')(format=".")
|
||||
+makeExcerpt('app/dashboard.component.ts ()','import-router', '')
|
||||
|
||||
+makeExample('toh-5/ts/app/dashboard.component.ts','ctor')(format=".")
|
||||
+makeExcerpt('app/dashboard.component.ts', 'ctor', '')
|
||||
|
||||
:marked
|
||||
Refresh the browser and select a hero from the dashboard; the app should navigate directly to that hero’s details.
|
||||
|
@ -1122,7 +1137,7 @@ code-example(format='').
|
|||
|
||||
在模板底部原来放`<my-hero-detail>`的地方添加下列HTML片段:
|
||||
|
||||
+makeExample('toh-5/ts/app/heroes.component.html','mini-detail')(format=".")
|
||||
+makeExcerpt('app/heroes.component.html', 'mini-detail', '')
|
||||
|
||||
:marked
|
||||
After clicking a hero, the user should see something like this below the hero list:
|
||||
|
@ -1136,12 +1151,12 @@ figure.image-display
|
|||
|
||||
### 使用*UpperCasePipe*格式化
|
||||
|
||||
Notice that the hero's name is displayed in CAPITAL LETTERS. That's the effect of the `UpperCasePipe`
|
||||
Notice that the hero's name is displayed in CAPITAL LETTERS. That's the effect of the `uppercase` pipe
|
||||
that we slipped into the interpolation binding. Look for it right after the pipe operator ( | ).
|
||||
|
||||
注意,英雄的名字全被显示成大写字母。那是 `UpperCasePipe`的效果,借助它,我们能插手“插值表达式绑定”的过程。去管道操作符 ( | ) 后面找它。
|
||||
注意,英雄的名字全被显示成大写字母。那是 `uppercase`管道的效果,借助它,我们能插手“插值表达式绑定”的过程。去管道操作符 ( | ) 后面找它。
|
||||
|
||||
+makeExample('toh-5/ts/app/heroes.component.html','pipe')(format=".")
|
||||
+makeExcerpt('app/heroes.component.html', 'pipe', '')
|
||||
|
||||
:marked
|
||||
Pipes are a good way to format strings, currency amounts, dates and other display data.
|
||||
|
@ -1176,19 +1191,33 @@ figure.image-display
|
|||
|
||||
在做更多修改之前,我们先把模板和样式移到它们自己的文件中去:
|
||||
|
||||
1. *Cut-and-paste* the template contents into a new `heroes.component.html` file.
|
||||
1. *Cut-and-paste* the template contents into a new <span ngio-ex>heroes.component.html</span> file.
|
||||
|
||||
1. 把模板内容*剪切并粘贴*到新的`heroes.component.html`文件。
|
||||
1. 把模板内容*剪切并粘贴*到新的<span ngio-ex>heroes.component.html</span>文件。
|
||||
|
||||
1. *Cut-and-paste* the styles contents into a new `heroes.component.css` file.
|
||||
1. *Cut-and-paste* the styles contents into a new <span ngio-ex>heroes.component.css</span> file.
|
||||
|
||||
1. 把样式内容*剪切并粘贴*到新的`heroes.component.css`文件。
|
||||
1. 把样式内容*剪切并粘贴*到新的<span ngio-ex>heroes.component.css</span>文件。
|
||||
|
||||
1. *Set* the component metadata's `templateUrl` and `styleUrls` properties to refer to both files.
|
||||
|
||||
1. *设置*组件元数据的`templateUrl`和`styleUrls`属性,来分别引用这两个文件。
|
||||
|
||||
+makeExample('toh-5/ts/app/heroes.component.ts', 'metadata', 'app/heroes.component.ts (revised metadata)')(format=".")
|
||||
.l-sub-section
|
||||
:marked
|
||||
The `styleUrls` property is !{_an} !{_array} of style file names (with paths).
|
||||
We could list multiple style files from different locations if we needed them.
|
||||
<span if-docs="ts">As with `templateUrl`, we must specify the path _all the way
|
||||
back to the application root_.</span>
|
||||
|
||||
`styleUrls`属性是一个由样式文件的文件名(包括路径)组成的数组。
|
||||
我们还可以列出来自多个不同位置的样式文件。
|
||||
和`templateUrl`一样,必须指定_相对于此应用根目录_的路径。
|
||||
|
||||
block heroes-component-cleanup
|
||||
//- Only relevant for Dart.
|
||||
|
||||
+makeExcerpt('app/heroes.component.ts (revised metadata)', 'metadata')
|
||||
|
||||
:marked
|
||||
Now we can see what's going on as we update the component class along the same lines as the dashboard:
|
||||
|
@ -1213,7 +1242,7 @@ figure.image-display
|
|||
|
||||
下面是修改过的组件类:
|
||||
|
||||
+makeExample('toh-5/ts/app/heroes.component.ts', 'class', 'app/heroes.component.ts (类)')
|
||||
+makeExcerpt('app/heroes.component.ts', 'class')
|
||||
|
||||
:marked
|
||||
Refresh the browser and start clicking.
|
||||
|
@ -1258,23 +1287,12 @@ figure.image-display
|
|||
如果我们把这60来行CSS粘贴到组件元数据的`styles`中,它们会完全淹没组件的工作逻辑。
|
||||
不能这么做。在一个独立的`*.css`文件中编辑CSS当然会更简单。
|
||||
|
||||
Add a `dashboard.component.css` file to the `app` folder and reference
|
||||
that file in the component metadata's `styleUrls` array property like this:
|
||||
Add a <span ngio-ex>dashboard.component.css</span> file to the `!{_appDir}` folder and reference
|
||||
that file in the component metadata's `styleUrls` !{_array} property like this:
|
||||
|
||||
把`dashboard.component.css`文件添加到`app`目录下,并在组件元数据的`styleUrls`数组属性中引用它。就像这样:
|
||||
把<span ngio-ex>dashboard.component.css</span>文件添加到`!{_appDir}`目录下,并在组件元数据的`styleUrls`数组属性中引用它。就像这样:
|
||||
|
||||
+makeExample('toh-5/ts/app/dashboard.component.ts', 'css', 'app/dashboard.component.ts (styleUrls)')(format=".")
|
||||
|
||||
:marked
|
||||
.l-sub-section
|
||||
:marked
|
||||
The `styleUrls` property is an array of style file names (with paths).
|
||||
We could list multiple style files from different locations if we needed them.
|
||||
As with `templateUrl`, we must specify the path _all the way back to the application root_.
|
||||
|
||||
`styleUrls`属性是一个由样式文件的文件名(包括路径)组成的数组。
|
||||
如果需要,我们还可以列出来自多个不同位置的样式文件。
|
||||
和`templateUrl`一样,我们必须指定_相对于此应用根目录_的路径。
|
||||
+makeExcerpt('app/dashboard.component.ts (styleUrls)', 'css')
|
||||
|
||||
:marked
|
||||
### Stylish Hero Details
|
||||
|
@ -1285,21 +1303,28 @@ figure.image-display
|
|||
|
||||
设计师还给了我们`HeroDetailComponent`特有的CSS风格。
|
||||
|
||||
Add a `hero-detail.component.css` to the `app` folder and refer to that file inside
|
||||
the `styleUrls` array as we did for `DashboardComponent`.
|
||||
Add a <span ngio-ex>hero-detail.component.css</span> to the `!{_appDir}`
|
||||
folder and refer to that file inside
|
||||
the `styleUrls` !{_array} as we did for `DashboardComponent`.
|
||||
Let's also remove the `hero` property `@Input` !{_decorator}
|
||||
<span if-docs="ts">and its import</span>
|
||||
while we are at it.
|
||||
|
||||
在`app`目录下添加`hero-detail.component.css`文件,并且在`styleUrls`数组中引用它 —— 就像当初在`DashboardComponent`中做过的那样。
|
||||
在`!{_appDir}`目录下添加<span ngio-ex>hero-detail.component.css</span>文件,
|
||||
并且在`styleUrls`数组中引用它 —— 就像当初在`DashboardComponent`中做过的那样。
|
||||
同时删除`hero``@Input`装饰器属性<span if-docs="ts">和它的导入语句</span>。
|
||||
|
||||
Here's the content for the aforementioned component CSS files.
|
||||
|
||||
上述组件的CSS文件内容如下:
|
||||
|
||||
+makeTabs(
|
||||
`toh-5/ts/app/hero-detail.component.css,
|
||||
toh-5/ts/app/dashboard.component.css`,
|
||||
null,
|
||||
`app/hero-detail.component.css,
|
||||
app/dashboard.component.css`)
|
||||
block css-files
|
||||
+makeTabs(
|
||||
`toh-5/ts/app/hero-detail.component.css,
|
||||
toh-5/ts/app/dashboard.component.css`,
|
||||
null,
|
||||
`app/hero-detail.component.css,
|
||||
app/dashboard.component.css`)
|
||||
|
||||
:marked
|
||||
### Style the Navigation Links
|
||||
|
@ -1312,34 +1337,34 @@ figure.image-display
|
|||
设计师还给了我们一些CSS,用于让`AppComponent`中的导航链接看起来更像可被选择的按钮。
|
||||
要让它们协同工作,我们得把那些链接包含在`<nav>`标签中。
|
||||
|
||||
Add a `app.component.css` file to the `app` folder with the following content.
|
||||
Add a <span ngio-ex>app.component.css</span> file to the `!{_appDir}` folder with the following content.
|
||||
|
||||
在`app`目录下添加一个`app.component.css`文件,内容如下:
|
||||
在`!{_appDir}`目录下添加一个<span ngio-ex>app.component.css</span>文件,内容如下:
|
||||
|
||||
+makeExample('toh-5/ts/app/app.component.css', '', 'app/app.component.css (navigation styles)')
|
||||
+makeExcerpt('app/app.component.css (navigation styles)', '')
|
||||
|
||||
.l-sub-section
|
||||
block router-link-active
|
||||
:marked
|
||||
**The *routerLinkActive* directive**
|
||||
|
||||
***routerLinkActive*指令**
|
||||
***routerLinkActive*指令**
|
||||
|
||||
The Angular Router provides a `routerLinkActive` directive we can use to
|
||||
add a class to the HTML navigation element whose route matches the active route.
|
||||
All we have to do is define the style for it. Sweet!
|
||||
|
||||
Angular路由器提供了`routerLinkActive`指令,我们可以用它来为匹配了活动路由的HTML导航元素自动添加一个CSS类。
|
||||
我们唯一要做的就是为它定义样式。真好!
|
||||
|
||||
The Angular Router provides a `routerLinkActive` directive we can use to
|
||||
add a class to the HTML navigation element whose route matches the active route.
|
||||
All we have to do is define the style for it. Sweet!
|
||||
|
||||
Angular路由器提供了`routerLinkActive`指令,我们可以用它来为匹配了活动路由的HTML导航元素自动添加一个CSS类。
|
||||
我们唯一要做的就是为它定义样式。真好!
|
||||
|
||||
+makeExample('toh-5/ts/app/app.component.ts', 'template', 'app/app.component.ts (active router links)')(format=".")
|
||||
+makeExcerpt('app/app.component.ts (active router links)', 'template')
|
||||
|
||||
:marked
|
||||
Set the `AppComponent`’s `styleUrls` property to this CSS file.
|
||||
|
||||
设置`AppComponent`的`styleUrls`属性,指向这个CSS文件。
|
||||
|
||||
+makeExample('toh-5/ts/app/app.component.ts','style-urls', 'app/app.component.ts (styleUrls)')(format=".")
|
||||
+makeExcerpt('app/app.component.ts','styleUrls')
|
||||
|
||||
:marked
|
||||
### Global application styles
|
||||
|
@ -1368,7 +1393,7 @@ figure.image-display
|
|||
[快速起步, "添加一些样式"](../quickstart.html#!#add-some-style))。
|
||||
下面是摘录:
|
||||
|
||||
+makeExample('toh-5/ts/styles.1.css', 'toh-excerpt', 'styles.css (app styles excerpt)')(format=".")
|
||||
+makeExcerpt('styles.css (excerpt)', 'toh')
|
||||
|
||||
- var styles_css = 'https://raw.githubusercontent.com/angular/angular.io/master/public/docs/_examples/styles.css'
|
||||
|
||||
|
@ -1379,16 +1404,16 @@ figure.image-display
|
|||
如果在根目录下没有一个名叫`styles.css`的文件,就添加它。
|
||||
确保它包含[这里给出的主样式](!{styles_css})。
|
||||
|
||||
If necessary, also edit `index.html` to refer to this stylesheet.
|
||||
If necessary, also edit <span ngio-ex>index.html</span> to refer to this stylesheet.
|
||||
|
||||
如有必要,也可以编辑`index.html`来引用这个样式表。
|
||||
如有必要,也可以编辑<span ngio-ex>index.html</span>来引用这个样式表。
|
||||
|
||||
+makeExample('toh-5/ts/index.html','css', 'index.html (link ref)')(format=".")
|
||||
+makeExcerpt('index.html (link ref)', 'css')
|
||||
|
||||
:marked
|
||||
Look at the app now. Our dashboard, heroes, and navigation links are styling!
|
||||
|
||||
看看现在的应用!我们的仪表盘、英雄列表和导航链接都漂亮多了!
|
||||
看看现在的应用!我们的仪表盘、英雄列表和导航链接都漂亮多了!
|
||||
|
||||
figure.image-display
|
||||
img(src='/resources/images/devguide/toh/dashboard-top-heroes.png' alt="查看导航栏")
|
||||
|
@ -1447,7 +1472,7 @@ block file-tree-end
|
|||
|
||||
### 走过的路
|
||||
|
||||
We travelled a great distance in this chapter.
|
||||
We travelled a great distance in this chapter
|
||||
|
||||
在本章中,我们往前走了很远:
|
||||
|
||||
|
@ -1459,9 +1484,9 @@ block file-tree-end
|
|||
|
||||
- 我们学会了如何创建路由链接来表示导航栏的菜单项。
|
||||
|
||||
- We used router parameters to navigate to the details of user selected hero.
|
||||
- We used router link parameters to navigate to the details of user selected hero.
|
||||
|
||||
- 我们使用路由参数来导航到用户所选的英雄详情。
|
||||
- 我们使用路由链接参数来导航到用户所选的英雄详情。
|
||||
|
||||
- We shared the `HeroService` among multiple components.
|
||||
|
||||
|
|
|
@ -352,9 +352,9 @@ block get-heroes-details
|
|||
|
||||
### Post
|
||||
|
||||
We are using `post` to add new heroes. Post requests require a little bit more setup than Get requests, but the format is as follows:
|
||||
We will be using `post` to add new heroes. Post requests require a little bit more setup than Get requests:
|
||||
|
||||
我们使用`post`来添加新的英雄。post请求比get请求稍多一点儿设置工作,大致写法如下:
|
||||
我们使用`post`来添加新的英雄。post请求比get请求稍多一点儿设置工作:
|
||||
|
||||
+makeExcerpt('app/hero.service.ts', 'post')
|
||||
|
||||
|
@ -593,11 +593,10 @@ block review
|
|||
figure.image-display
|
||||
img(src='/resources/images/devguide/toh/toh-http.anim.gif' alt="Heroes List Editing w/ HTTP")
|
||||
|
||||
block observables-section
|
||||
:marked
|
||||
## !{_Observable}s
|
||||
|
||||
## 可观察对象(Observable)
|
||||
:marked
|
||||
## !{_Observable}s
|
||||
|
||||
## 可观察对象(Observable)
|
||||
|
||||
block observables-section-intro
|
||||
:marked
|
||||
|
|
Loading…
Reference in New Issue