498 lines
24 KiB
Plaintext
498 lines
24 KiB
Plaintext
include ../_util-fns
|
||
|
||
:marked
|
||
# It Takes Many Heroes
|
||
# 需要多个英雄
|
||
Our story needs more heroes.
|
||
We’ll expand our Tour of Heroes app to display a list of heroes,
|
||
allow the user to select a hero, and display the hero’s details.
|
||
|
||
我们的故事需要更多的英雄了。我们将扩展这个《英雄指南》,来显示一个英雄列表,允许用户选择一个英雄,并且显示英雄的详情。
|
||
|
||
[Run the live example for part 2](/resources/live-examples/toh-2/ts/plnkr.html)
|
||
|
||
[运行第二部分的在线例子](/resources/live-examples/toh-2/ts/plnkr.html)
|
||
|
||
Let’s take stock of what we’ll need to display a list of heroes.
|
||
First, we need a list of heroes. We want to display those heroes in the view’s template,
|
||
so we’ll need a way to do that.
|
||
|
||
我们来盘点一下显示英雄列表都需要些什么。
|
||
首先,我们需要一份英雄列表数据。我们还要把这些英雄显示到一个视图的模板中,所以,我们需要用某种途径来做到这一点。
|
||
|
||
.l-main-section
|
||
:marked
|
||
## Where We Left Off
|
||
## 我们在哪儿
|
||
Before we continue with Part 2 of the Tour of Heroes,
|
||
let’s verify we have the following structure after [Part 1](./toh-pt1.html).
|
||
If not, we’ll need to go back to Part 1 and figure out what we missed.
|
||
|
||
在继续《英雄指南》的第二部分之前,我们先检查一下,完成[第一部分](./toh-pt1.html)之后,你是否已经有了如下目录结构。如果没有,你得先回到第一部分,看看错过了哪里。
|
||
|
||
.filetree
|
||
.file angular2-tour-of-heroes
|
||
.children
|
||
.file app
|
||
.children
|
||
.file app.component.ts
|
||
.file main.ts
|
||
.file node_modules ...
|
||
.file typings ...
|
||
.file index.html
|
||
.file package.json
|
||
.file styles.css
|
||
.file systemjs.config.js
|
||
.file tsconfig.json
|
||
.file typings.json
|
||
:marked
|
||
### Keep the app transpiling and running
|
||
### 让应用代码保持转译和运行
|
||
We want to start the TypeScript compiler, have it watch for changes, and start our server. We'll do this by typing
|
||
|
||
我们要启动TypeScript编译器,它会监视文件变更,并启动开发服务器。我们只要敲:
|
||
|
||
code-example(format="." language="bash").
|
||
npm start
|
||
|
||
:marked
|
||
This will keep the application running while we continue to build the Tour of Heroes.
|
||
|
||
这个命令会在我们构建《英雄指南》的时候让应用得以持续运行。
|
||
|
||
.l-main-section
|
||
:marked
|
||
## Displaying Our Heroes
|
||
## 显示我们的英雄
|
||
### Creating heroes
|
||
### 创建英雄
|
||
Let’s create an array of ten heroes at the bottom of `app.component.ts`.
|
||
|
||
我们先在`app.component.ts`的底部创建一个由十位英雄组成的数组。
|
||
|
||
+makeExample('toh-2/ts/app/app.component.ts', 'hero-array', 'app.component.ts (英雄数组)')
|
||
|
||
:marked
|
||
The `HEROES` array is of type `Hero`, the class defined in part one,
|
||
to create an array of heroes.
|
||
We aspire to fetch this list of heroes from a web service, but let’s take small steps
|
||
first and display mock heroes.
|
||
|
||
`HEROES`变量是一个由`Hero`类的实例构成的数组,我们在第一部分定义过它。
|
||
我们当然希望从一个Web服务中获取这个英雄列表,但别急,我们得把步子迈得小一点儿 —— 先用一组Mock(模拟)出来的英雄。
|
||
|
||
### Exposing heroes
|
||
### 导出英雄们
|
||
Let’s create a property in `AppComponent` that exposes the heroes for binding.
|
||
|
||
我们在`AppComponent`上创建一个属性,用来导出这些英雄,以供绑定。
|
||
|
||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'hero-array-1', 'app.component.ts (英雄数组属性)')
|
||
|
||
:marked
|
||
We did not have to define the `heroes` type. TypeScript can infer it from the `HEROES` array.
|
||
|
||
我们并不需要明确定义`heroes`属性的数据类型,TypeScript能从`HEROES`数组中推断出来。
|
||
.l-sub-section
|
||
:marked
|
||
We could have defined the heroes list here in this component class.
|
||
But we know that ultimately we’ll get the heroes from a data service.
|
||
Because we know where we are heading, it makes sense to separate the hero data
|
||
from the class implementation from the start.
|
||
|
||
我们已经把英雄列表定义在了这个组件类中。
|
||
但显然,我们最终还是得从一个数据服务中获取这些英雄。
|
||
正因如此,我们从一开始就要有意识的把英雄数据隔离到一个类中来实现。
|
||
:marked
|
||
### Displaying heroes in a template
|
||
### 在一个模板中显示英雄
|
||
Our component has `heroes`. Let’s create an unordered list in our template to display them.
|
||
We’ll insert the following chunk of HTML below the title and above the hero details.
|
||
|
||
我们的组件有了`heroes`属性,我们再到模板中创建一个无序列表来显示他们。
|
||
我们将在标题和英雄详情之间,插入下面这段HTML代码。
|
||
|
||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'heroes-template-1', 'app.component.ts (英雄模板)')
|
||
|
||
:marked
|
||
Now we have a template that we can fill with our heroes.
|
||
|
||
现在,我们有了一个模板。接下来,就用英雄们的数据来填充它。
|
||
|
||
### Listing heroes with ngFor
|
||
### 通过ngFor来显示英雄列表
|
||
|
||
We want to bind the array of `heroes` in our component to our template, iterate over them,
|
||
and display them individually.
|
||
We’ll need some help from Angular to do this. Let’s do this step by step.
|
||
|
||
我们想要把组件中的`heroes`数组绑定到模板中,迭代并逐个儿显示他们。
|
||
这下,我们就得借助Angular的帮助来完成它了。我们来一步步儿实现它!
|
||
|
||
First modify the `<li>` tag by adding the built-in directive `*ngFor`.
|
||
|
||
首先,修改`<li>`标记,往上添加内建指令:`*ngFor`。
|
||
|
||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'heroes-ngfor-1', 'app.component.ts (ngFor)')
|
||
|
||
.alert.is-critical
|
||
:marked
|
||
The leading asterisk (`*`) in front of `ngFor` is a critical part of this syntax.
|
||
|
||
`ngFor`的前导星号(`*`)是此语法的重要组成部分。
|
||
|
||
.l-sub-section
|
||
:marked
|
||
The (`*`) prefix to `ngFor` indicates that the `<li>` element and its children
|
||
constitute a master template.
|
||
|
||
`ngFor`的`*`前缀表示`<li>`及其子元素组成了一个主控模板。
|
||
|
||
The `ngFor` directive iterates over the `heroes` array returned by the `AppComponent.heroes` property
|
||
and stamps out instances of this template.
|
||
|
||
`ngFor`指令在`AppComponent.heroes`属性返回的`heroes`数组上迭代,并输出此模板的实例。
|
||
|
||
The quoted text assigned to `ngFor` means
|
||
“*take each hero in the `heroes` array, store it in the local `hero` variable,
|
||
and make it available to the corresponding template instance*”.
|
||
|
||
引号中赋值给`ngFor`的那段儿文本表示“*从`heroes`数组中取出每个英雄,存入一个局部的`hero`变量,并让它在相应的模板实例中可用*”。
|
||
|
||
The `let` keyword before "hero" identifies the `hero` as a template input variable.
|
||
We can reference this variable within the template to access a hero’s properties.
|
||
|
||
`hero`前的`let`关键字表示`hero`是一个模板输入变量。
|
||
在模板中,我们可以引用这个变量来访问一位英雄的属性。
|
||
|
||
Learn more about `ngFor` and template input variables in the
|
||
[Displaying Data](../guide/displaying-data.html#ngFor) and
|
||
[Template Syntax](../guide/template-syntax.html#ngFor) chapters.
|
||
|
||
要学习更多关于`ngFor`和模板输入变量的知识,参见[显示数据](../guide/displaying-data.html#ngFor)和
|
||
[模板语法](../guide/template-syntax.html#ngFor)两章。
|
||
|
||
:marked
|
||
Now we insert some content between the `<li>` tags
|
||
that uses the `hero` template variable to display the hero’s properties.
|
||
|
||
现在,我们在`<li>`标记中插入一些内容,以便使用模板变量`hero`来显示英雄的属性。
|
||
|
||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'ng-for', 'app.component.ts (ngFor模板)')(format=".")
|
||
|
||
:marked
|
||
When the browser refreshes, we see a list of heroes!
|
||
|
||
当浏览器刷新时,我们就看到了英雄列表。
|
||
|
||
### Styling our heroes
|
||
### 给我们的英雄们“美容”
|
||
Our list of heroes looks pretty bland.
|
||
We want to make it visually obvious to a user which hero we are hovering over and which hero is selected.
|
||
|
||
我们的英雄列表看起来实在是稀松平常。
|
||
但当用户的鼠标划过英雄或选中了一个英雄时,我们得让他/他看起来醒目一点。
|
||
|
||
Let’s add some styles to our component by setting the `styles` property on the `@Component` decorator
|
||
to the following CSS classes:
|
||
|
||
要想给我们的组件添加一些样式,请把`@Component`装饰器的`styles`属性设置为下列CSS类:
|
||
|
||
+makeExample('toh-2/ts/app/app.component.ts', 'styles-1', 'app.component.ts (添加样式)')
|
||
|
||
:marked
|
||
Notice that we again use the back-tick notation for multi-line strings.
|
||
|
||
注意,我们又使用了反引号语法来书写多行字符串。
|
||
|
||
When we assign styles to a component they are scoped to that specific component.
|
||
Our styles will only apply to our `AppComponent` and won't "leak" to the outer HTML.
|
||
|
||
当我们把样式赋予一个组件时,它们的作用范围将仅限于该组件。
|
||
即:此样式只会作用于这个`AppComponent`组件,而不会“泄露”到外部HTML中。
|
||
|
||
Our template for displaying the heroes should now look like this:
|
||
|
||
用于显示英雄们的这个模板看起来像这样:
|
||
|
||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'heroes-styled', 'app.component.ts (带样式的英雄们)')
|
||
|
||
:marked
|
||
That's a lot of styles! We can put them inline as shown here, or we can move them out to their own file which will make it easier to code our component.
|
||
We'll do this in a later chapter. For now let's keep rolling.
|
||
|
||
样式有很多种写法!我们可以像这里一样内联在代码中,也可以把它们移出去,放到各自的文件中,以便给组件编码时更容易。
|
||
等到后面的章节中我们肯定会这么干,但现在,还是保持现在的节奏吧。
|
||
|
||
.l-main-section
|
||
:marked
|
||
## Selecting a Hero
|
||
## 选择英雄
|
||
We have a list of heroes and we have a single hero displayed in our app.
|
||
The list and the single hero are not connected in any way.
|
||
We want the user to select a hero from our list, and have the selected hero appear in the details view.
|
||
This UI pattern is widely known as "master-detail".
|
||
In our case, the master is the heroes list and the detail is the selected hero.
|
||
|
||
在我们的应用中,已经有了英雄列表页以及一个单独的英雄显示页。
|
||
但列表和单独的英雄之间还没有任何关联。
|
||
我们希望用户在列表中选中一个英雄,然后让这个被选中的英雄出现在详情视图中。
|
||
这种UI布局模式,通常被称为“主从式”。
|
||
在这个例子中,主视图是英雄列表,从视图则是被选中的英雄。
|
||
|
||
Let’s connect the master to the detail through a `selectedHero` component property bound to a click event.
|
||
|
||
我们通过组件中的一个`selectedHero`属性来连接主从视图。它被绑定到了click事件上。
|
||
|
||
### Click event
|
||
### click事件
|
||
We modify the `<li>` by inserting an Angular event binding to its click event.
|
||
|
||
我们往`<li>`元素上插入一句Angular事件绑定代码,绑定到它的click事件。
|
||
|
||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'selectedHero-click', 'app.component.ts (捕获click事件)')
|
||
|
||
:marked
|
||
Focus on the event binding
|
||
|
||
事件绑定详解
|
||
code-example(format="." language="bash").
|
||
(click)="onSelect(hero)"
|
||
:marked
|
||
The parenthesis identify the `<li>` element’s `click` event as the target.
|
||
The expression to the right of the equal sign calls the `AppComponent` method, `onSelect()`,
|
||
passing the template input variable `hero` as an argument.
|
||
That’s the same `hero` variable we defined previously in the `ngFor`.
|
||
|
||
圆括号表示`<li>`元素上的`click`事件就是我们要绑定的目标。
|
||
等号右边的表达式调用`AppComponent`的`onSelect()`方法,并把模板输入变量`hero`作为参数传进去。
|
||
它和我们前面在`ngFor`中定义的`hero`变量是同一个。
|
||
|
||
.l-sub-section
|
||
:marked
|
||
Learn more about Event Binding in the
|
||
[User Input](../guide/user-input.html) and
|
||
[Templating Syntax](../guide/template-syntax.html#event-binding) chapters.
|
||
|
||
要学习关于事件绑定的更多知识,参见:
|
||
[用户输入](../guide/user-input.html) 和
|
||
[模板语法](../guide/template-syntax.html#event-binding)两章。
|
||
|
||
:marked
|
||
### Add the click handler
|
||
### 添加click事件处理器
|
||
Our event binding refers to an `onSelect` method that doesn’t exist yet.
|
||
We’ll add that method to our component now.
|
||
|
||
我们的事件绑定引用了`onSelect`方法,但它还不存在。
|
||
我们现在就把它添加到组件上。
|
||
|
||
What should that method do? It should set the component’s selected hero to the hero that the user clicked.
|
||
|
||
这个方法该做什么?它应该把组件中被选中的英雄设置为用户刚刚点击的那个。
|
||
|
||
Our component doesn’t have a “selected hero” yet either. We’ll start there.
|
||
|
||
我们的组件还没有用来表示“当前选中的英雄”的变量,我们就从这一步儿开始。
|
||
|
||
### Expose the selected hero
|
||
### 导出“当前选中的英雄”
|
||
|
||
We no longer need the static `hero` property of the `AppComponent`.
|
||
**Replace** it with this simple `selectedHero` property:
|
||
|
||
在`AppComponent`上,我们不再需要一个固定的`hero`属性。
|
||
那就直接把它改为`selectedHero`属性。
|
||
|
||
+makeExample('toh-2/ts/app/app.component.ts', 'selected-hero-1', 'app.component.ts (selectedHero)')
|
||
|
||
:marked
|
||
We’ve decided that none of the heroes should be selected before the user picks a hero so
|
||
we won’t initialize the `selectedHero` as we were doing with `hero`.
|
||
|
||
我们已决定:在用户选取之前,不会默认选择任何英雄,所以,我们不用像`hero`一样去初始化`selectedHero`变量。
|
||
|
||
Now **add an `onSelect` method** that sets the `selectedHero` property to the `hero` the user clicked.
|
||
|
||
现在,**添加一个`onSelect`方法**,以便在用户点击一个英雄的时候,把它赋给`selectedHero`属性。
|
||
+makeExample('toh-2/ts/app/app.component.ts', 'on-select-1', 'app.component.ts (onSelect)')
|
||
|
||
:marked
|
||
We will be showing the selected hero's details in our template.
|
||
At the moment, it is still referring to the old `hero` property.
|
||
Let’s fix the template to bind to the new `selectedHero` property.
|
||
|
||
我们将把所选英雄的详细信息显示在模板中。目前,它仍然引用的是以前的`hero`属性。
|
||
我们这就修改模板,让它绑定到新的`selectedHero`属性上去。
|
||
|
||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'selectedHero-details', 'app.component.ts (绑定到selectedHero的名字上)')
|
||
:marked
|
||
### Hide the empty detail with ngIf
|
||
### 利用ngIf隐藏空的详情
|
||
|
||
When our app loads we see a list of heroes, but a hero is not selected.
|
||
The `selectedHero` is `undefined`.
|
||
That’s why we'll see the following error in the browser’s console:
|
||
|
||
当应用刚加载时,我们会看到一个英雄列表,但还没有任何英雄被选中。
|
||
`selectedHero`属性是`undefined`。
|
||
因此,我们会看到浏览器控制台中出现下列错误:
|
||
code-example(language="html").
|
||
EXCEPTION: TypeError: Cannot read property 'name' of undefined in [null]
|
||
|
||
:marked
|
||
Remember that we are displaying `selectedHero.name` in the template.
|
||
This name property does not exist because `selectedHero` itself is undefined.
|
||
|
||
记住,我们要在模板中显示的是`selectedHero.name`。
|
||
显然,这个name属性是不存在的,因为`selectedHero`本身还是`undefined`呢。
|
||
|
||
We'll address this problem by keeping the hero detail out of the DOM until there is a selected hero.
|
||
|
||
要处理这个问题,我们可以先让英雄详情不要出现在DOM中 —— 直到有英雄被选中。
|
||
|
||
We wrap the HTML hero detail content of our template with a `<div>`.
|
||
Then we add the `ngIf` built-in directive and set it to the `selectedHero` property of our component.
|
||
|
||
我们把模板中的“英雄详情”内容区用div包裹起来。然后往上添加一个`ngIf`内建指令,然后把`ngIf`的值设置为本组件的`selectedHero`属性。
|
||
|
||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'ng-if', 'app.component.ts (ngIf)')
|
||
|
||
.alert.is-critical
|
||
:marked
|
||
Remember that the leading asterisk (`*`) in front of `ngIf` is
|
||
a critical part of this syntax.
|
||
|
||
记住,`ngIf`前面的星号(`*`)是语法中的重要组成部分。
|
||
:marked
|
||
When there is no `selectedHero`, the `ngIf` directive removes the hero detail HTML from the DOM.
|
||
There will be no hero detail elements and no bindings to worry about.
|
||
|
||
当没有`selectedHero`时,`ngIf`指令会从DOM中移除表示英雄详情的这段HTML。
|
||
没有了表示英雄详情的元素,也就不用担心绑定问题。
|
||
|
||
When the user picks a hero, `selectedHero` becomes "truthy" and
|
||
`ngIf` puts the hero detail content into the DOM and evaluates the nested bindings.
|
||
|
||
当用户选取了一个英雄,`selectedHero`变成了真值,于是`ngIf`把“英雄详情”加回DOM中,并且计算它所嵌套的各种绑定。
|
||
.l-sub-section
|
||
:marked
|
||
`ngIf` and `ngFor` are called “structural directives” because they can change the
|
||
structure of portions of the DOM.
|
||
In other words, they give structure to the way Angular displays content in the DOM.
|
||
|
||
`ngIf`和`ngFor`被称为“结构型指令”,因为它们可以修改DOM的部分结构。
|
||
换句话说,它们让Angular在DOM中显示内容的方式结构化了。
|
||
|
||
Learn more about `ngIf`, `ngFor` and other structural directives in the
|
||
[Structural Directives](../guide/structural-directives.html) and
|
||
[Template Syntax](../guide/template-syntax.html#directives) chapters.
|
||
|
||
要了解更多`ngIf`,`ngFor`和其它结构型指令,请参阅:
|
||
[结构型指令](../guide/structural-directives.html)和
|
||
[模板语法](../guide/template-syntax.html#directives)章节。
|
||
|
||
:marked
|
||
The browser refreshes and we see the list of heroes but not the selected hero detail.
|
||
The `ngIf` keeps it out of the DOM as long as the `selectedHero` is undefined.
|
||
When we click on a hero in the list, the selected hero displays in the hero details.
|
||
Everything is working as we expect.
|
||
|
||
浏览器刷新了,我们看到了一个英雄列表,但是还没有选中的英雄详情。
|
||
当`selectedHero`是`undefined`时,`ngIf`会保证英雄详情不出现在DOM中。
|
||
当我们从列表中点击一个英雄时,选中的英雄被显示在英雄详情里。
|
||
正如我们所预期的那样。
|
||
|
||
### Styling the selection
|
||
### 给所选英雄添加样式
|
||
|
||
We see the selected hero in the details area below but we can’t quickly locate that hero in the list above.
|
||
We can fix that by applying the `selected` CSS class to the appropriate `<li>` in the master list.
|
||
For example, when we select Magneta from the heroes list,
|
||
we can make it pop out visually by giving it a subtle background color as shown here.
|
||
|
||
我们在下面的详情区看到了选中的英雄,但是我们还是没法在上面的列表区快速的找到这位英雄。
|
||
通过把CSS类`selected`添加到主列表的`<li>`元素上,我们可以解决这个问题。
|
||
比如,当我们在列表区选中了Magneta时,我们可以通过设置一个轻微的背景色来让他略显突出。
|
||
|
||
figure.image-display
|
||
img(src='/resources/images/devguide/toh/heroes-list-selected.png' alt="选中的英雄")
|
||
:marked
|
||
We’ll add a property binding on `class` for the `selected` class to the template. We'll set this to an expression that compares the current `selectedHero` to the `hero`.
|
||
|
||
我们将通过一个在`class`属性上的绑定,来把`selected`类添加到模板上。我们把这个绑定表达式设置为`selectedHero`和`hero`的比较结果,
|
||
|
||
The key is the name of the CSS class (`selected`). The value is `true` if the two heroes match and `false` otherwise.
|
||
We’re saying “*apply the `selected` class if the heroes match, remove it if they don’t*”.
|
||
|
||
关键是CSS类的名字:`selected`。当两位英雄一致时,它为`true`,否则为`false`。
|
||
也就是说:“*当两位英雄匹配时,应用上`selected`类,否则不应用*”。
|
||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'class-selected-1', 'app.component.ts (设置CSS类)')(format=".")
|
||
:marked
|
||
Notice in the template that the `class.selected` is surrounded in square brackets (`[]`).
|
||
This is the syntax for a Property Binding, a binding in which data flows one way
|
||
from the data source (the expression `hero === selectedHero`) to a property of `class`.
|
||
|
||
注意,模板中的`class.selected`是括在一对方括号中的。
|
||
这就是“属性绑定”的语法,一种从数据源(即`hero === selectedHero`表达式)到`class`属性的单向数据流。
|
||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'class-selected-2', 'app.component.ts (Styling each hero)')(format=".")
|
||
|
||
.l-sub-section
|
||
:marked
|
||
Learn more about [Property Binding](../guide/template-syntax.html#property-binding)
|
||
in the Template Syntax chapter.
|
||
|
||
学习关于[属性绑定](../guide/template-syntax.html#property-binding)
|
||
的更多知识,参见“模板语法”一章。
|
||
|
||
:marked
|
||
The browser reloads our app.
|
||
We select the hero Magneta and the selection is clearly identified by the background color.
|
||
|
||
浏览器重新加载了你的应用。
|
||
我们选中英雄Magneta,于是他通过背景色的变化被清晰的标记了出来。
|
||
figure.image-display
|
||
img(src='/resources/images/devguide/toh/heroes-list-1.png' alt="英雄列表应用的输出")
|
||
|
||
:marked
|
||
We select a different hero and the tell-tale color switches to that hero.
|
||
|
||
我们选择了另一个英雄,于是色标也跟着移到了这位英雄上。
|
||
|
||
Here's the complete `app.component.ts` as it stands now:
|
||
|
||
完整的`app.component.ts`文件如下:
|
||
|
||
+makeExample('toh-2/ts/app/app.component.ts', 'pt2', 'app.component.ts')
|
||
|
||
.l-main-section
|
||
:marked
|
||
## The Road We’ve Travelled
|
||
## 已走的路
|
||
Here’s what we achieved in this chapter:
|
||
|
||
在本章中,我们达成了这些:
|
||
|
||
* Our Tour of Heroes now displays a list of selectable heroes
|
||
* 我们的《英雄指南》现在显示一个可选英雄的列表
|
||
* We added the ability to select a hero and show the hero’s details
|
||
* 我们添加了选择英雄的能力,并且会显示这个英雄的详情
|
||
* We learned how to use the built-in directives `ngIf` and `ngFor` in a component’s template
|
||
* 我们学会了如何在组件模板中使用内建的`ngIf`和`ngFor`指令
|
||
|
||
[Run the live example for part 2](/resources/live-examples/toh-2/ts/plnkr.html)
|
||
|
||
[运行第二部分的在线例子](/resources/live-examples/toh-2/ts/plnkr.html)
|
||
|
||
### The Road Ahead
|
||
### 前方的路
|
||
Our Tour of Heroes has grown, but it’s far from complete.
|
||
We can't put the entire app into a single component.
|
||
We need to break it up into sub-components and teach them to work together
|
||
as we learn in the [next chapter](toh-pt3.html).
|
||
|
||
我们的《英雄指南》长大了,但还远远不够完善。
|
||
我们显然不能把整个应用都放进一个组件中。
|
||
我们需要把它拆分成一系列子组件,然后教它们协同工作 ——
|
||
就像我们将在[下一章](toh-pt3.html)学到的那样。
|