2017-11-06 13:02:18 -05:00
# Display a Heroes List
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
# 显示英雄列表
2017-03-27 11:08:53 -04:00
In this page, you'll expand the Tour of Heroes app to display a list of heroes, and
allow users to select a hero and display the hero's details.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
本页中,你将扩展《英雄指南》应用,让它显示一个英雄列表,
并允许用户选择一个英雄,查看该英雄的详细信息。
2018-03-07 02:42:49 -05:00
2017-11-06 13:02:18 -05:00
## Create mock heroes
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
## 创建模拟( mock) 的英雄数据
2017-11-06 13:02:18 -05:00
You'll need some heroes to display.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
你需要一些英雄数据以供显示。
2017-11-06 13:02:18 -05:00
Eventually you'll get them from a remote data server.
For now, you'll create some _mock heroes_ and pretend they came from the server.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
最终,你会从远端的数据服务器获取它。
不过目前,你要先创建一些*模拟的英雄数据*,并假装它们是从服务器上取到的。
2017-11-06 13:02:18 -05:00
Create a file called `mock-heroes.ts` in the `src/app/` folder.
Define a `HEROES` constant as an array of ten heroes and export it.
The file should look like this.
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
在 `src/app/` 文件夹中创建一个名叫 `mock-heroes.ts` 的文件。
定义一个包含十个英雄的常量数组 `HEROES` ,并导出它。
该文件是这样的。
2017-11-06 13:02:18 -05:00
< code-example path = "toh-pt2/src/app/mock-heroes.ts" linenums = "false"
2017-11-09 22:35:38 -05:00
title="src/app/mock-heroes.ts">
2018-03-03 08:06:01 -05:00
2017-02-22 13:09:39 -05:00
< / code-example >
2017-03-27 11:08:53 -04:00
## Displaying heroes
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
## 显示这些英雄
2018-03-07 02:42:49 -05:00
2017-11-06 13:02:18 -05:00
You're about to display the list of heroes at the top of the `HeroesComponent` .
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
你要在 `HeroesComponent` 的顶部显示这个英雄列表。
2017-11-06 13:02:18 -05:00
Open the `HeroesComponent` class file and import the mock `HEROES` .
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
打开 `HeroesComponent` 类文件,并导入模拟的 `HEROES` 。
2017-11-06 13:02:18 -05:00
< code-example path = "toh-pt2/src/app/heroes/heroes.component.ts" region = "import-heroes" title = "src/app/heroes/heroes.component.ts (import HEROES)" >
2018-03-03 08:06:01 -05:00
2017-03-27 11:08:53 -04:00
< / code-example >
2017-02-22 13:09:39 -05:00
2017-11-06 13:02:18 -05:00
Add a `heroes` property to the class that exposes these heroes for binding.
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
往类中添加一个 `heroes` 属性,这样可以暴露出这些英雄,以供绑定。
2017-11-06 13:02:18 -05:00
< code-example path = "toh-pt2/src/app/heroes/heroes.component.ts" region = "heroes" >
2018-03-03 08:06:01 -05:00
2017-03-27 11:08:53 -04:00
< / code-example >
2017-02-22 13:09:39 -05:00
2017-11-06 13:02:18 -05:00
### List heroes with _*ngFor_
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
### 使用 `*ngFor` 列出这些英雄
2017-11-06 13:02:18 -05:00
Open the `HeroesComponent` template file and make the following changes:
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
打开 `HeroesComponent` 的模板文件,并做如下修改:
2017-11-06 13:02:18 -05:00
* Add an `<h2>` at the top,
2018-03-03 08:06:01 -05:00
2018-03-08 04:07:55 -05:00
在顶部添加 `<h2>` ,
2017-11-06 13:02:18 -05:00
* Below it add an HTML unordered list (`< ul > `)
2018-03-03 08:06:01 -05:00
2018-03-08 04:07:55 -05:00
然后添加表示无序列表的 HTML 元素(`< ul > `)
2017-11-06 13:02:18 -05:00
* Insert an `<li>` within the `<ul>` that displays properties of a `hero` .
2018-03-03 08:06:01 -05:00
2018-03-08 04:07:55 -05:00
在 `<ul>` 中插入一个 `<li>` 元素,以显示单个 `hero` 的属性。
2017-11-06 13:02:18 -05:00
* Sprinkle some CSS classes for styling (you'll add the CSS styles shortly).
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
点缀上一些 CSS 类(稍后你还会添加更多 CSS 样式)。
2017-11-06 13:02:18 -05:00
Make it look like this:
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
做完之后应该是这样的:
2017-11-06 13:02:18 -05:00
< code-example path = "toh-pt2/src/app/heroes/heroes.component.1.html" region = "list" title = "heroes.component.html (heroes template)" linenums = "false" >
2018-03-03 08:06:01 -05:00
2017-03-27 11:08:53 -04:00
< / code-example >
2017-11-06 13:02:18 -05:00
Now change the `<li>` to this:
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
现在,把 `<li>` 修改成这样:
2017-11-06 13:02:18 -05:00
< code-example path = "toh-pt2/src/app/heroes/heroes.component.1.html" region = "li" >
2018-03-03 08:06:01 -05:00
2017-03-27 11:08:53 -04:00
< / code-example >
2017-11-06 13:02:18 -05:00
The [`*ngFor` ](guide/template-syntax#ngFor ) is Angular's _repeater_ directive.
It repeats the host element for each element in a list.
2017-03-27 11:08:53 -04:00
2018-03-08 04:07:55 -05:00
[`*ngFor` ](guide/template-syntax#ngFor ) 是一个 Angular 的复写器( repeater) 指令。
它会为列表中的每项数据复写它的宿主元素。
2017-11-06 13:02:18 -05:00
In this example
2017-03-27 11:08:53 -04:00
2018-03-08 04:07:55 -05:00
在这个例子中
2017-11-06 13:02:18 -05:00
* `<li>` is the host element
2018-03-03 08:06:01 -05:00
2018-03-08 04:07:55 -05:00
`<li>` 就是 `*ngFor` 的宿主元素
2017-11-06 13:02:18 -05:00
* `heroes` is the list from the `HeroesComponent` class.
2018-03-03 08:06:01 -05:00
2018-03-08 04:07:55 -05:00
`heroes` 就是来自 `HeroesComponent` 类的列表。
2018-03-06 22:25:56 -05:00
* `hero` holds the current hero object for each iteration through the list.
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
当依次遍历这个列表时,`hero` 会为每个迭代保存当前的英雄对象。
2017-11-06 13:02:18 -05:00
< div class = "alert is-important" >
2017-02-22 13:09:39 -05:00
2017-11-06 13:02:18 -05:00
Don't forget the asterisk (*) in front of `ngFor` . It's a critical part of the syntax.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
不要忘了 `ngFor` 前面的星号(`*`),它是该语法中的关键部分。
2017-04-10 11:51:13 -04:00
< / div >
2017-03-27 11:08:53 -04:00
2017-11-06 13:02:18 -05:00
After the browser refreshes, the list of heroes appears.
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
浏览器刷新之后,英雄列表出现了。
2017-11-06 13:02:18 -05:00
{@a styles}
2017-03-27 11:08:53 -04:00
### Style the heroes
2018-03-08 04:07:55 -05:00
### 给英雄们“美容”
2018-03-07 02:42:49 -05:00
2017-11-06 13:02:18 -05:00
The heroes list should be attractive and should respond visually when users
hover over and select a hero from the list.
2017-03-27 11:08:53 -04:00
2018-03-08 04:07:55 -05:00
英雄列表应该富有吸引力,并且当用户把鼠标移到某个英雄上和从列表中选中某个英雄时,应该给出视觉反馈。
2017-11-06 13:02:18 -05:00
In the [first tutorial ](tutorial/toh-pt0#app-wide-styles ), you set the basic styles for the entire application in `styles.css` .
That stylesheet didn't include styles for this list of heroes.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
在[教程的第一章](tutorial/toh-pt0#app-wide-styles),你曾在 `styles.css` 中为整个应用设置了一些基础的样式。
但那个样式表并不包含英雄列表所需的样式。
2017-11-06 13:02:18 -05:00
You could add more styles to `styles.css` and keep growing that stylesheet as you add components.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
固然,你可以把更多样式加入到 `styles.css` ,并且放任它随着你添加更多组件而不断膨胀。
2017-11-06 13:02:18 -05:00
You may prefer instead to define private styles for a specific component and keep everything a component needs— the code, the HTML,
and the CSS — together in one place.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
但还有更好的方式。你可以定义属于特定组件的私有样式, 并且让组件所需的一切( 代码、HTML 和 CSS) 都放在一起。
2017-11-06 13:02:18 -05:00
This approach makes it easier to re-use the component somewhere else
and deliver the component's intended appearance even if the global styles are different.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
这种方式让你在其它地方复用该组件更加容易,并且即使全局样式和这里不一样,组件也仍然具有期望的外观。
2017-11-06 13:02:18 -05:00
You define private styles either inline in the `@Component.styles` array or
as stylesheet file(s) identified in the `@Component.styleUrls` array.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
你可以用多种方式定义私有样式,或者内联在 `@Component.styles` 数组中,或者在 `@Component.styleUrls` 所指出的样式表文件中。
2017-11-06 13:02:18 -05:00
When the CLI generated the `HeroesComponent` , it created an empty `heroes.component.css` stylesheet for the `HeroesComponent`
and pointed to it in `@Component.styleUrls` like this.
2017-03-27 11:08:53 -04:00
2018-03-08 04:07:55 -05:00
当 CLI 生成 `HeroesComponent` 时,它也同时为 `HeroesComponent` 创建了空白的 `heroes.component.css` 样式表文件,并且让 `@Component.styleUrls` 指向它,就像这样:
2017-11-06 13:02:18 -05:00
< code-example path = "toh-pt2/src/app/heroes/heroes.component.ts" region = "metadata"
title="src/app/heroes/heroes.component.ts (@Component)">
2018-03-03 08:06:01 -05:00
2017-02-22 13:09:39 -05:00
< / code-example >
2017-11-06 13:02:18 -05:00
Open the `heroes.component.css` file and paste in the private CSS styles for the `HeroesComponent` .
You'll find them in the [final code review ](#final-code-review ) at the bottom of this guide.
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
打开 `heroes.component.css` 文件,并且把 `HeroesComponent` 的私有 CSS 样式粘贴进去。
你可以在本指南底部的[查看最终代码](#final-code-review)中找到它们。
2017-11-06 13:02:18 -05:00
< div class = "alert is-important" >
2017-03-31 19:57:13 -04:00
2017-11-06 13:02:18 -05:00
Styles and stylesheets identified in `@Component` metadata are scoped to that specific component.
The `heroes.component.css` styles apply only to the `HeroesComponent` and don't affect the outer HTML or the HTML in any other component.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
`@Component` 元数据中指定的样式和样式表都是局限于该组件的。
`heroes.component.css` 中的样式只会作用于 `HeroesComponent` ,既不会影响到组件外的 HTML, 也不会影响到其它组件中的 HTML。
2017-04-10 11:51:13 -04:00
< / div >
2017-03-27 11:08:53 -04:00
2017-11-06 13:02:18 -05:00
## Master/Detail
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
## 主从结构
2017-11-06 13:02:18 -05:00
When the user clicks a hero in the **master** list,
the component should display the selected hero's **details** at the bottom of the page.
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
当用户在**主**列表中点击一个英雄时,该组件应该在页面底部显示所选英雄的**详情**。
2017-11-06 13:02:18 -05:00
In this section, you'll listen for the hero item click event
and update the hero detail.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
在本节,你将监听英雄条目的点击事件,并更新英雄的详情。
2017-11-06 13:02:18 -05:00
### Add a click event binding
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
### 添加 `click` 事件绑定
2017-11-06 13:02:18 -05:00
Add a click event binding to the `<li>` like this:
2017-02-22 13:09:39 -05:00
2018-03-07 02:42:49 -05:00
我们再往`< li > `元素上插入一句点击事件的绑定代码:
2017-11-06 13:02:18 -05:00
< code-example path = "toh-pt2/src/app/heroes/heroes.component.1.html" region = "selectedHero-click" title = "heroes.component.html (template excerpt)" linenums = "false" >
2018-03-03 08:06:01 -05:00
2017-03-27 11:08:53 -04:00
< / code-example >
2017-02-22 13:09:39 -05:00
2017-11-06 13:02:18 -05:00
This is an example of Angular's [event binding ](guide/template-syntax#event-binding ) syntax.
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
这是 Angular [事件绑定 ](guide/template-syntax#event-binding ) 语法的例子。
2017-11-06 13:02:18 -05:00
The parentheses around `click` tell Angular to listen for the `<li>` element's `click` event.
When the user clicks in the `<li>` , Angular executes the `onSelect(hero)` expression.
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
`click` 外面的圆括号会让 Angular 监听这个 `<li>` 元素的 `click` 事件。
当用户点击 `<li>` 时, Angular 就会执行表达式 `onSelect(hero)` 。
2017-11-06 13:02:18 -05:00
`onSelect()` is a `HeroesComponent` method that you're about to write.
Angular calls it with the `hero` object displayed in the clicked `<li>` ,
the same `hero` defined previously in the `*ngFor` expression.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
`onSelect()` 是 `HeroesComponent` 上的一个方法,你很快就要写它。
Angular 会把所点击的 `<li>` 上的 `hero` 对象传给它,这个 `hero` 也就是以前在 `*ngFor` 表达式中定义的那个。
2017-11-06 13:02:18 -05:00
### Add the click event handler
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
### 添加 `click` 事件处理器
2017-11-06 13:02:18 -05:00
Rename the component's `hero` property to `selectedHero` but don't assign it.
There is no _selected hero_ when the application starts.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
把该组件的 `hero` 属性改名为 `selectedHero` ,但不要为它赋值。
因为应用刚刚启动时并没有*所选英雄*。
2017-11-06 13:02:18 -05:00
Add the following `onSelect()` method, which assigns the clicked hero from the template
to the component's `selectedHero` .
2017-03-27 11:08:53 -04:00
2018-03-08 04:07:55 -05:00
添加如下 `onSelect()` 方法,它会把模板中被点击的英雄赋值给组件的 `selectedHero` 属性。
2017-11-06 13:02:18 -05:00
< code-example path = "toh-pt2/src/app/heroes/heroes.component.ts" region = "on-select" title = "src/app/heroes/heroes.component.ts (onSelect)" linenums = "false" >
2018-03-03 08:06:01 -05:00
2017-03-27 11:08:53 -04:00
< / code-example >
2017-02-22 13:09:39 -05:00
2017-11-06 13:02:18 -05:00
### Update the details template
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
### 修改详情模板
2017-11-06 13:02:18 -05:00
The template still refers to the component's old `hero` property which no longer exists.
Rename `hero` to `selectedHero` .
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
该模板引用的仍然是老的 `hero` 属性,但它已经不存在了。
把 `hero` 改名为 `selectedHero` 。
2017-11-06 13:02:18 -05:00
< code-example path = "toh-pt2/src/app/heroes/heroes.component.html" region = "selectedHero-details" title = "heroes.component.html (selected hero details)" linenums = "false" >
2018-03-03 08:06:01 -05:00
2017-02-22 13:09:39 -05:00
< / code-example >
2017-11-06 13:02:18 -05:00
### Hide empty details with _*ngIf_
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
### 使用 `*ngIf` 隐藏空白的详情
2017-11-06 13:02:18 -05:00
After the browser refreshes, the application is broken.
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
刷新浏览器,应用挂了。
2017-11-06 13:02:18 -05:00
Open the browser developer tools and look in the console for an error message like this:
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
打开浏览器的开发者工具,它的控制台中显示出如下错误信息:
2017-11-06 13:02:18 -05:00
< code-example language = "sh" class = "code-shell" >
2018-03-03 08:06:01 -05:00
2017-11-06 13:02:18 -05:00
HeroesComponent.html:3 ERROR TypeError: Cannot read property 'name' of undefined
2018-03-03 08:06:01 -05:00
2017-03-27 11:08:53 -04:00
< / code-example >
2017-02-22 13:09:39 -05:00
2017-11-06 13:02:18 -05:00
Now click one of the list items.
The app seems to be working again.
The heroes appear in a list and details about the clicked hero appear at the bottom of the page.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
现在,从列表中随便点击一个条目。
应用又正常了。
英雄们显示在列表中,并且所点英雄的详情也显示在了页面的下方。
2017-11-06 13:02:18 -05:00
#### What happened?
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
#### 怎么回事?
2017-11-06 13:02:18 -05:00
When the app starts, the `selectedHero` is `undefined` _by design_ .
2017-03-27 11:08:53 -04:00
2018-03-08 04:07:55 -05:00
当应用启动时,`selectedHero` 是 `undefined` , *设计如此*。
2017-11-06 13:02:18 -05:00
Binding expressions in the template that refer to properties of `selectedHero` — expressions like `{{selectedHero.name}}` — _must fail_ because there is no selected hero.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
但模板中的绑定表达式引用了 `selectedHero` 的属性(表达式为`{{selectedHero.name}}`),这必然会失败,因为你还没选过英雄呢。
2017-11-06 13:02:18 -05:00
#### The fix
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
#### 修复
2017-11-06 13:02:18 -05:00
The component should only display the selected hero details if the `selectedHero` exists.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
该组件应该只有当 `selectedHero` 存在时才显示所选英雄的详情。
2017-11-06 13:02:18 -05:00
Wrap the hero detail HTML in a `<div>` .
Add Angular's `*ngIf` directive to the `<div>` and set it to `selectedHero` .
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
把显示英雄详情的 HTML 包裹在一个`< div > `中。
并且为这个 div 添加 Angular 的 `*ngIf` 指令,把它的值设置为 `selectedHero` 。
2017-11-06 13:02:18 -05:00
< div class = "alert is-important" >
2017-02-22 13:09:39 -05:00
2017-11-06 13:02:18 -05:00
Don't forget the asterisk (*) in front of `ngIf` . It's a critical part of the syntax.
2017-03-27 11:08:53 -04:00
2018-03-08 04:07:55 -05:00
不要忘了 `ngIf` 前面的星号(`*`),它是该语法中的关键部分。
2017-11-06 13:02:18 -05:00
< / div >
2017-03-31 19:57:13 -04:00
2017-11-06 13:02:18 -05:00
< code-example path = "toh-pt2/src/app/heroes/heroes.component.html" region = "ng-if" title = "src/app/heroes/heroes.component.html (*ngIf)" linenums = "false" >
2018-03-03 08:06:01 -05:00
2017-11-06 13:02:18 -05:00
< / code-example >
2017-03-31 19:57:13 -04:00
2017-11-06 13:02:18 -05:00
After the browser refreshes, the list of names reappears.
The details area is blank.
Click a hero and its details appear.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
浏览器刷新之后,英雄名字的列表又出现了。
详情部分仍然是空。
点击一个英雄,它的详情就出现了。
2017-11-06 13:02:18 -05:00
#### Why it works
2017-03-27 11:08:53 -04:00
2018-03-08 04:07:55 -05:00
#### 为什么改好了?
2017-11-06 13:02:18 -05:00
When `selectedHero` is undefined, the `ngIf` removes the hero detail from the DOM. There are no `selectedHero` bindings to worry about.
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
当 `selectedHero` 为 `undefined` 时,`ngIf` 从 DOM 中移除了英雄详情。因此也就不用担心 `selectedHero` 的绑定了。
2017-11-06 13:02:18 -05:00
When the user picks a hero, `selectedHero` has a value and
`ngIf` puts the hero detail into the DOM.
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
当用户选择一个英雄时,`selectedHero` 也就有了值,并且 `ngIf` 把英雄的详情放回到 DOM 中。
2017-03-27 11:08:53 -04:00
### Style the selected hero
2018-03-07 02:42:49 -05:00
### 给所选英雄添加样式
2017-11-06 13:02:18 -05:00
It's difficult to identify the _selected hero_ in the list when all `<li>` elements look alike.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
所有的 `<li>` 元素看起来都是一样的,因此很难从列表中识别出*所选英雄*。
2017-11-06 13:02:18 -05:00
If the user clicks "Magneta", that hero should render with a distinctive but subtle background color like this:
2017-03-30 15:04:18 -04:00
2018-03-08 04:07:55 -05:00
如果用户点击了“Magneta”, 这个英雄应该用一个略有不同的背景色显示出来, 就像这样:
2017-05-09 18:53:32 -04:00
< figure >
2017-11-06 13:02:18 -05:00
2017-05-09 18:53:32 -04:00
< img src = 'generated/images/guide/toh/heroes-list-selected.png' alt = "Selected hero" >
2017-02-22 13:09:39 -05:00
2017-11-06 13:02:18 -05:00
< / figure >
2017-03-31 19:57:13 -04:00
2017-11-06 13:02:18 -05:00
That _selected hero_ coloring is the work of the `.selected` CSS class in the [styles you added earlier ](#styles ).
You just have to apply the `.selected` class to the `<li>` when the user clicks it.
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
*所选英雄*的颜色来自于[你前面添加的样式](#styles)中的 CSS 类 `.selected` 。
所以你只要在用户点击一个 `<li>` 时把 `.selected` 类应用到该元素上就可以了。
2017-11-06 13:02:18 -05:00
The Angular [class binding ](guide/template-syntax#class-binding ) makes it easy to add and remove a CSS class conditionally.
Just add `[class.some-css-class]="some-condition"` to the element you want to style.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
Angular 的 [CSS 类绑定 ](guide/template-syntax#class-binding )机制让根据条件添加或移除一个 CSS 类变得很容易。
只要把 `[class.some-css-class]="some-condition"` 添加到你要施加样式的元素上就可以了。
2017-11-06 13:02:18 -05:00
Add the following `[class.selected]` binding to the `<li>` in the `HeroesComponent` template:
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
在 `HeroesComponent` 模板中的 `<li>` 元素上添加 `[class.selected]` 绑定,代码如下:
2017-11-06 13:02:18 -05:00
< code-example path = "toh-pt2/src/app/heroes/heroes.component.1.html" region = "class-selected" title = "heroes.component.html (toggle the 'selected' CSS class)" linenums = "false" >
2018-03-03 08:06:01 -05:00
2017-03-27 11:08:53 -04:00
< / code-example >
2017-11-06 13:02:18 -05:00
When the current row hero is the same as the `selectedHero` , Angular adds the `selected` CSS class. When the two heroes are different, Angular removes the class.
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
如果当前行的英雄和 `selectedHero` 相同, Angular 就会添加 CSS 类 `selected` ,否则就会移除它。
2017-11-06 13:02:18 -05:00
The finished `<li>` looks like this:
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
最终的 `<li>` 是这样的:
2017-11-06 13:02:18 -05:00
< code-example path = "toh-pt2/src/app/heroes/heroes.component.html" region = "li" title = "heroes.component.html (list item hero)" linenums = "false" >
2017-03-27 11:08:53 -04:00
< / code-example >
2017-11-06 13:02:18 -05:00
{@a final-code-review}
2017-03-31 19:57:13 -04:00
2017-11-06 13:02:18 -05:00
## Final code review
2017-03-31 19:57:13 -04:00
2018-03-08 04:07:55 -05:00
## 查看最终代码
2017-11-06 13:02:18 -05:00
Your app should look like this < live-example > < / live-example > .
2017-02-22 13:09:39 -05:00
2018-03-07 02:42:49 -05:00
我们的应用现在变成了这样:< live-example > < / live-example > 。
2017-11-06 13:02:18 -05:00
Here are the code files discussed on this page, including the `HeroesComponent` styles.
2017-02-22 13:09:39 -05:00
2018-03-08 04:07:55 -05:00
下面是本页面中所提及的代码文件,包括 `HeroesComponent` 的样式。
2017-11-06 13:02:18 -05:00
< code-tabs >
2018-03-06 23:26:05 -05:00
2017-11-06 13:02:18 -05:00
< code-pane title = "src/app/heroes/heroes.component.ts" path = "toh-pt2/src/app/heroes/heroes.component.ts" >
< / code-pane >
2017-02-22 13:09:39 -05:00
2017-11-06 13:02:18 -05:00
< code-pane title = "src/app/heroes/heroes.component.html" path = "toh-pt2/src/app/heroes/heroes.component.html" >
< / code-pane >
2017-03-31 19:57:13 -04:00
2017-11-06 13:02:18 -05:00
< code-pane title = "src/app/heroes/heroes.component.css" path = "toh-pt2/src/app/heroes/heroes.component.css" >
< / code-pane >
2018-03-06 23:26:05 -05:00
2017-11-06 13:02:18 -05:00
< / code-tabs >
2017-03-31 19:57:13 -04:00
2017-09-27 16:45:47 -04:00
## Summary
2017-03-31 19:57:13 -04:00
2018-03-03 08:06:01 -05:00
## 小结
2017-11-06 13:02:18 -05:00
* The Tour of Heroes app displays a list of heroes in a Master/Detail view.
2018-03-03 08:06:01 -05:00
2018-03-08 04:07:55 -05:00
英雄指南应用在一个主从视图中显示了英雄列表。
2017-11-06 13:02:18 -05:00
* The user can select a hero and see that hero's details.
2018-03-03 08:06:01 -05:00
2018-03-08 04:07:55 -05:00
用户可以选择一个英雄,并查看该英雄的详情。
2017-11-06 13:02:18 -05:00
* You used `*ngFor` to display a list.
2018-03-03 08:06:01 -05:00
2018-03-08 04:07:55 -05:00
你使用 `*ngFor` 显示了一个列表。
2017-11-06 13:02:18 -05:00
* You used `*ngIf` to conditionally include or exclude a block of HTML.
2018-03-03 08:06:01 -05:00
2018-03-08 04:07:55 -05:00
你使用 `*ngIf` 来根据条件包含或排除了一段 HTML。
2017-11-06 13:02:18 -05:00
* You can toggle a CSS style class with a `class` binding.
2018-03-08 04:07:55 -05:00
你可以用 `class` 绑定来切换 CSS 的样式类。