把display的译法从“展示”批量改为“显示”

译完第二章
This commit is contained in:
Zhicheng Wang 2016-04-14 21:45:12 +08:00
parent 0bb5c4f37b
commit 37d5fbcf1c
5 changed files with 189 additions and 25 deletions

View File

@ -183,7 +183,7 @@ include _util-fns
to a [View](#view) and handling most of the views display to a [View](#view) and handling most of the views display
and user-interaction logic. and user-interaction logic.
组件是一个用来展示数据到[视图](#view)并处理几乎所有视图显示以及用户交互逻辑的Angular类Angular Class 组件是一个用来在[视图](#view)中显示数据并处理几乎所有视图显示以及用户交互逻辑的Angular类Angular Class
The Component is one of the most important building blocks in the Angular system. The Component is one of the most important building blocks in the Angular system.
It is, in fact, an Angular [Directive](#directive) with a companion [Template](#template). It is, in fact, an Angular [Directive](#directive) with a companion [Template](#template).
@ -233,7 +233,7 @@ include _util-fns
Applications display data values to a user and respond to user Applications display data values to a user and respond to user
actions (clicks, touches, keystrokes). actions (clicks, touches, keystrokes).
应用程序一般将数据示给用户,并对用户的操作(点击、触屏、按键)做出回应。 应用程序一般将数据示给用户,并对用户的操作(点击、触屏、按键)做出回应。
We could push application data values into HTML, attach We could push application data values into HTML, attach
event listeners, pull changed values from the screen, and event listeners, pull changed values from the screen, and

View File

@ -31,7 +31,7 @@
"forms": { "forms": {
"title": "表单", "title": "表单",
"intro": "表单创建一个有机、有效、引人注目的数据输入体验。Angular表单协调一组数据绑定控件跟踪变更验证输入的有效性并且示错误信息。", "intro": "表单创建一个有机、有效、引人注目的数据输入体验。Angular表单协调一组数据绑定控件跟踪变更验证输入的有效性并且示错误信息。",
"nextable": true, "nextable": true,
"basics": true "basics": true
}, },

View File

@ -59,7 +59,7 @@ include ../_util-fns
Here's a visual idea of where we're going in this tour, beginning with the "Dashboard" Here's a visual idea of where we're going in this tour, beginning with the "Dashboard"
view and our most heroic heroes: view and our most heroic heroes:
在这个教程中还有一些可视化思想。放一个“黑板报Dashboard”视图示我们最勇敢的英雄。 在这个教程中还有一些可视化思想。放一个“黑板报Dashboard”视图示我们最勇敢的英雄。
figure.image-display figure.image-display
img(src='/resources/images/devguide/toh/heroes-dashboard-1.png' alt="英雄黑板报的输出") img(src='/resources/images/devguide/toh/heroes-dashboard-1.png' alt="英雄黑板报的输出")

View File

@ -56,7 +56,7 @@ code-example(format="" language="bash").
.l-main-section .l-main-section
:marked :marked
## Show our Hero ## Show our Hero
## 示我们的英雄 ## 示我们的英雄
We want to display Hero data in our app We want to display Hero data in our app
我们要在我们的应用中显示英雄数据 我们要在我们的应用中显示英雄数据
@ -89,7 +89,7 @@ code-example(format="" language="bash").
:marked :marked
Learn more about interpolation in the [Displaying Data chapter](../guide/displaying-data.html). Learn more about interpolation in the [Displaying Data chapter](../guide/displaying-data.html).
想了解插值表达式的更多知识,参阅[“示数据”一章](../guide/displaying-data.html)。 想了解插值表达式的更多知识,参阅[“示数据”一章](../guide/displaying-data.html)。
:marked :marked
### Hero object ### Hero object
### Hero对象 ### Hero对象
@ -134,8 +134,8 @@ code-example(format="" language="bash").
Displaying a name is good, but we want to see all of our heros properties. Displaying a name is good, but we want to see all of our heros properties.
Well add a `<div>` for our heros `id` property and another `<div>` for our heros `name`. Well add a `<div>` for our heros `id` property and another `<div>` for our heros `name`.
示名字就算不错了,但是我们还想看到我们这位英雄的所有属性。 示名字就算不错了,但是我们还想看到我们这位英雄的所有属性。
我们将添加一个`<div>`来展示英雄的`id`属性,另一个`<div>`来展示英雄的`name`属性。 我们将添加一个`<div>`来显示英雄的`id`属性,另一个`<div>`来显示英雄的`name`属性。
+makeExample('toh-1/ts-snippets/app.component.snippets.pt1.ts', 'show-hero-properties') +makeExample('toh-1/ts-snippets/app.component.snippets.pt1.ts', 'show-hero-properties')
:marked :marked

View File

@ -7,7 +7,7 @@ include ../_util-fns
Well expand our Tour of Heroes app to display a list of heroes, Well expand our Tour of Heroes app to display a list of heroes,
allow the user to select a hero, and display the heros details. allow the user to select a hero, and display the heros details.
我们的故事需要更多的英雄。我们将扩展我们的《英雄之旅》,来显示一个英雄列表,运行用户选择一个英雄,并且示英雄的详情。 我们的故事需要更多的英雄。我们将扩展我们的《英雄之旅》,来显示一个英雄列表,运行用户选择一个英雄,并且示英雄的详情。
[Run the live example for part 2](/resources/live-examples/toh-2/ts/plnkr.html) [Run the live example for part 2](/resources/live-examples/toh-2/ts/plnkr.html)
@ -17,7 +17,7 @@ include ../_util-fns
First, we need a list of heroes. We want to display those heroes in the views template, First, we need a list of heroes. We want to display those heroes in the views template,
so well need a way to do that. so well need a way to do that.
我们来清点一下示英雄列表都需要点什么。 我们来清点一下示英雄列表都需要点什么。
首先,我们需要一个英雄列表数据。我们还要把这些英雄显示到一个视图的模板中,所以,我们需要用某种途径来做到这一点。 首先,我们需要一个英雄列表数据。我们还要把这些英雄显示到一个视图的模板中,所以,我们需要用某种途径来做到这一点。
.l-main-section .l-main-section
@ -61,7 +61,7 @@ code-example(format="." language="bash").
.l-main-section .l-main-section
:marked :marked
## Displaying Our Heroes ## Displaying Our Heroes
## 示我们的英雄 ## 示我们的英雄
### Creating heroes ### Creating heroes
### 创建英雄 ### 创建英雄
Lets create an array of ten heroes at the bottom of `app.component.ts`. Lets create an array of ten heroes at the bottom of `app.component.ts`.
@ -77,114 +77,183 @@ code-example(format="." language="bash").
first and display mock heroes. first and display mock heroes.
`HEROS`变量是一个由`Hero`类的实例构成的数组,我们在第一部分定义过它。 `HEROS`变量是一个由`Hero`类的实例构成的数组,我们在第一部分定义过它。
我们当然希望从一个Web服务中获取这个英雄列表但是不要急,我们得把步子迈得小一点 —— 先用一组Mock模拟对象出来的英雄。 我们当然希望从一个Web服务中获取这个英雄列表但是急,我们得把步子迈得小一点 —— 先用一组Mock模拟对象出来的英雄。
### Exposing heroes ### Exposing heroes
### 导出英雄们
Lets create a property in `AppComponent` that exposes the heroes for binding. Lets create a property in `AppComponent` that exposes the heroes for binding.
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'hero-array-1', 'app.component.ts (Hero array property)') 我们在`AppComponent`上创建一个属性,用来导出英雄们,以供绑定。
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'hero-array-1', 'app.component.ts (英雄数组属性)')
:marked :marked
We did not have to define the `heroes` type. TypeScript can infer it from the `HEROES` array. We did not have to define the `heroes` type. TypeScript can infer it from the `HEROES` array.
我们并不需要明确定义`heroes`属性的类型TypeScript能从`HEROES`数组中推断出来。
.l-sub-section .l-sub-section
:marked :marked
We could have defined the heroes list here in this component class. We could have defined the heroes list here in this component class.
But we know that ultimately well get the heroes from a data service. But we know that ultimately well get the heroes from a data service.
Because we know where we are heading, it makes sense to separate the hero data Because we know where we are heading, it makes sense to separate the hero data
from the class implementation from the start. from the class implementation from the start.
我们已经把英雄列表定义在了这个组件类中。
但是显然,我们最后还是得从一个数据服务中获取这些英雄。
正因如此,我们从一开始就有意识的把英雄数据隔离到一个类中来实现。
:marked :marked
### Displaying heroes in a template ### Displaying heroes in a template
### 在一个模板中显示英雄
Our component has `heroes`. Lets create an unordered list in our template to display them. Our component has `heroes`. Lets create an unordered list in our template to display them.
Well insert the following chunk of HTML below the title and above the hero details. Well insert the following chunk of HTML below the title and above the hero details.
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'heroes-template-1', 'app.component.ts (Heroes template)') 我们的组件有`heroes`属性,我们来到模板中创建一个无序列表来显示他们。
我们将在标题和英雄详情之间插入下面这段HTML代码。
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'heroes-template-1', 'app.component.ts (英雄模板)')
:marked :marked
Now we have a template that we can fill with our heroes. Now we have a template that we can fill with our heroes.
现在,我们有了一个模板,接下来,我们用英雄们的数据来填充它。
### Listing heroes with ngFor ### Listing heroes with ngFor
### 通过ngFor来显示英雄列表
We want to bind the array of `heroes` in our component to our template, iterate over them, We want to bind the array of `heroes` in our component to our template, iterate over them,
and display them individually. and display them individually.
Well need some help from Angular to do this. Lets do this step by step. Well need some help from Angular to do this. Lets do this step by step.
我们想要把组件中的`heroes`数组绑定到模板中,迭代并逐个显示他们。
这下我们就得借助Angular的帮助来完成它了。让我们一步步的实现它
First modify the `<li>` tag by adding the built-in directive `*ngFor`. 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)') +makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'heroes-ngfor-1', 'app.component.ts (ngFor)')
.alert.is-critical .alert.is-critical
:marked :marked
The leading asterisk (`*`) in front of `ngFor` is a critical part of this syntax. The leading asterisk (`*`) in front of `ngFor` is a critical part of this syntax.
`ngFor`前面的星号(`*`)是此语法的重要组成部分。
.l-sub-section .l-sub-section
:marked :marked
The (`*`) prefix to `ngFor` indicates that the `<li>` element and its children The (`*`) prefix to `ngFor` indicates that the `<li>` element and its children
constitute a master template. constitute a master template.
`ngFor`的`*`前缀表示`<li>`及其子元素组成了一个主控模板。
The `ngFor` directive iterates over the `heroes` array returned by the `AppComponent.heroes` property The `ngFor` directive iterates over the `heroes` array returned by the `AppComponent.heroes` property
and stamps out instances of this template. and stamps out instances of this template.
`ngFor`指令在`AppComponent.heroes`属性返回的`heroes`数组上迭代,并且输出此模板的实例。
The quoted text assigned to `ngFor` means The quoted text assigned to `ngFor` means
“*take each hero in the `heroes` array, store it in the local `hero` variable, “*take each hero in the `heroes` array, store it in the local `hero` variable,
and make it available to the corresponding template instance*”. and make it available to the corresponding template instance*”.
引号中赋值给`ngFor`的那段文本表示“*从`heroes`数组中取出每个英雄,存入一个局部的`hero`变量,并让它在其对应的模板实例中可用*”
The `#` prefix before "hero" identifies the `hero` as a local template variable. The `#` prefix before "hero" identifies the `hero` as a local template variable.
We can reference this variable within the template to access a heros properties. We can reference this variable within the template to access a heros properties.
`hero`前的`#`前缀表示`hero`是一个局部的模板变量。
在模板中,我们可以引用这个变量来存取一位英雄的属性。
Learn more about `ngFor` and local template variables in the Learn more about `ngFor` and local template variables in the
[Displaying Data](../guide/displaying-data.html#ngFor) and [Displaying Data](../guide/displaying-data.html#ngFor) and
[Template Syntax](../guide/template-syntax.html#ngFor) chapters. [Template Syntax](../guide/template-syntax.html#ngFor) chapters.
学习关于`ngFor`和局部模板变量的知识,参见[显示数据](../guide/displaying-data.html#ngFor)和
[模板语法](../guide/template-syntax.html#ngFor)章节。
:marked :marked
Now we insert some content between the `<li>` tags Now we insert some content between the `<li>` tags
that uses the `hero` template variable to display the heros properties. that uses the `hero` template variable to display the heros properties.
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'ng-for', 'app.component.ts (ngFor template)')(format=".") 现在,我们在`<li>`标记中插入一些内容,以便使用模板变量`hero`来显示英雄的属性。
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'ng-for', 'app.component.ts (ngFor模板)')(format=".")
:marked :marked
When the browser refreshes, we see a list of heroes! When the browser refreshes, we see a list of heroes!
当浏览器刷新时,我们就看到了英雄列表。
### Styling our heroes ### Styling our heroes
### 给我们的英雄们“美容”
Our list of heroes looks pretty bland. 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. We want to make it visually obvious to a user which hero we are hovering over and which hero is selected.
我们的英雄列表看起来实在是稀松平常。
但当用户的鼠标划过英雄或选中了一个英雄时,我们得让他看起来醒目一点。
Lets add some styles to our component by setting the `styles` property on the `@Component` decorator Lets add some styles to our component by setting the `styles` property on the `@Component` decorator
to the following CSS classes: to the following CSS classes:
+makeExample('toh-2/ts/app/app.component.ts', 'styles-1', 'app.component.ts (Styling)') 要想给我们的组件添加一些样式,请把`@Component`装饰器的`styles`属性设置为下列CSS类
+makeExample('toh-2/ts/app/app.component.ts', 'styles-1', 'app.component.ts (添加样式)')
:marked :marked
Notice that we again use the back-tick notation for multi-line strings. 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. 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. 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: 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 (Styled heroes)') 用于显示英雄们的这个模板看起来像这样:
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'heroes-styled', 'app.component.ts (带样式的英雄们)')
:marked :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. 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. We'll do this in a later chapter. For now let's keep rolling.
样式有很多种写法!我们可以像这里一样内联在代码中,或者我们可以把它们移出去,放到各自的文件中,以便为组件编码时更容易。
到后面的章节中我们就会这么干,但现在,我们还是保持现在的节奏。
.l-main-section .l-main-section
:marked :marked
## Selecting a Hero ## Selecting a Hero
## 选择英雄
We have a list of heroes and we have a single hero displayed in our app. 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. 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. 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". 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. In our case, the master is the heroes list and the detail is the selected hero.
在我们的应用中,已经有了英雄列表页以及一个单独的英雄显示页。
但列表和单独的英雄之间还没有任何关联。
我们希望用户在列表中选中一个英雄,然后让这个被选中的英雄出现在详情视图中。
这种UI布局模式通常被称为“主从式”。
在这个例子中,主视图是英雄列表,从视图则是被选中的英雄。
Lets connect the master to the detail through a `selectedHero` component property bound to a click event. Lets connect the master to the detail through a `selectedHero` component property bound to a click event.
我们通过组件中一个叫`selectedHero`的属性来连接主从视图。它被绑定到了一个click事件上。
### Click event ### Click event
### click事件
We modify the `<li>` by inserting an Angular event binding to its click event. We modify the `<li>` by inserting an Angular event binding to its click event.
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'selectedHero-click', 'app.component.ts (Capturing the click event)') 我们往`<li>`元素上插入一个Angular事件绑定代码来绑定到click事件上。
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'selectedHero-click', 'app.component.ts (捕获click事件)')
:marked :marked
Focus on the event binding Focus on the event binding
事件绑定详解
code-example(format="." language="bash"). code-example(format="." language="bash").
(click)="onSelect(hero)" (click)="onSelect(hero)"
:marked :marked
@ -192,31 +261,57 @@ code-example(format="." language="bash").
The expression to the right of the equal sign calls the `AppComponent` method, `onSelect()`, The expression to the right of the equal sign calls the `AppComponent` method, `onSelect()`,
passing the local template variable `hero` as an argument. passing the local template variable `hero` as an argument.
Thats the same `hero` variable we defined previously in the `ngFor`. Thats the same `hero` variable we defined previously in the `ngFor`.
圆括号表示`<li>`元素上的`click`事件是我们要绑定的目标。
等号右边的表达式调用`AppComponent`的`onSelect()`方法,并把局部模板变量`hero`作为参数传进去。
它和我们前面在`ngFor`中定义的`hero`变量是同一个。
.l-sub-section .l-sub-section
:marked :marked
Learn more about Event Binding in the Learn more about Event Binding in the
[User Input](../guide/user-input.html) and [User Input](../guide/user-input.html) and
[Templating Syntax](../guide/template-syntax.html#event-binding) chapters. [Templating Syntax](../guide/template-syntax.html#event-binding) chapters.
要学习更多关于事件绑定的知识,参见:
[用户输入](../guide/user-input.html) 和
[模板语法](../guide/template-syntax.html#event-binding)章节。
:marked :marked
### Add the click handler ### Add the click handler
### 添加click事件处理器
Our event binding refers to an `onSelect` method that doesnt exist yet. Our event binding refers to an `onSelect` method that doesnt exist yet.
Well add that method to our component now. Well add that method to our component now.
我们的事件绑定引用了`onSelect`方法,但它还不存在。
我们现在就把它添加到组件上。
What should that method do? It should set the components selected hero to the hero that the user clicked. What should that method do? It should set the components selected hero to the hero that the user clicked.
这个方法该做什么?它应该把组件中当前选中的英雄设置为用户刚刚点击的这个。
Our component doesnt have a “selected hero” yet either. Well start there. Our component doesnt have a “selected hero” yet either. Well start there.
我们的组件还没有用来表示“当前选中的英雄”的变量,我们就从这一步开始。
### Expose the selected hero ### Expose the selected hero
### 导出“当前选中的英雄”
We no longer need the static `hero` property of the `AppComponent`. We no longer need the static `hero` property of the `AppComponent`.
**Replace** it with this simple `selectedHero` property: **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)') +makeExample('toh-2/ts/app/app.component.ts', 'selected-hero-1', 'app.component.ts (selectedHero)')
:marked :marked
Weve decided that none of the heroes should be selected before the user picks a hero so Weve decided that none of the heroes should be selected before the user picks a hero so
we wont initialize the `selectedHero` as we were doing with `hero`. we wont 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. 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)') +makeExample('toh-2/ts/app/app.component.ts', 'on-select-1', 'app.component.ts (onSelect)')
:marked :marked
@ -224,14 +319,21 @@ code-example(format="." language="bash").
At the moment, it is still referring to the old `hero` property. At the moment, it is still referring to the old `hero` property.
Lets fix the template to bind to the new `selectedHero` property. Lets fix the template to bind to the new `selectedHero` property.
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'selectedHero-details', 'app.component.ts (Binding to the selectedHero\'s name)') 我们将把所选英雄的详细信息显示在模板中。目前,它仍然引用的是以前的`hero`属性。
我们这就修改模板,让它绑定到新的`selectedHero`属性上。
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'selectedHero-details', 'app.component.ts (绑定到selectedHero的名字上)')
:marked :marked
### Hide the empty detail with ngIf ### Hide the empty detail with ngIf
### 通过ngIf隐藏空的详情
When our app loads we see a list of heroes, but a hero is not selected. When our app loads we see a list of heroes, but a hero is not selected.
The `selectedHero` is `undefined`. The `selectedHero` is `undefined`.
Thats why we'll see the following error in the browsers console: Thats why we'll see the following error in the browsers console:
当应用刚加载时,我们会看到一个英雄列表,但是还没有任何英雄被选中。
`selectedHero`属性是`undefined`。
因此,我们会看到浏览器控制台中出现下列错误:
code-example(language="html"). code-example(language="html").
EXCEPTION: TypeError: Cannot read property 'name' of undefined in [null] EXCEPTION: TypeError: Cannot read property 'name' of undefined in [null]
@ -239,58 +341,97 @@ code-example(format="." language="bash").
Remember that we are displaying `selectedHero.name` in the template. Remember that we are displaying `selectedHero.name` in the template.
This name property does not exist because `selectedHero` itself is undefined. 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. 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>`. 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. Then we add the `ngIf` built-in directive and set it to the `selectedHero` property of our component.
我们把模板中的“英雄详情”内容区用div包裹起来。然后把一个`ngIf`内置指令添加上去,然后把它的值设置为本组件的`selectedHero`属性。
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'ng-if', 'app.component.ts (ngIf)') +makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'ng-if', 'app.component.ts (ngIf)')
.alert.is-critical .alert.is-critical
:marked :marked
Remember that the leading asterisk (`*`) in front of `ngIf` is Remember that the leading asterisk (`*`) in front of `ngIf` is
a critical part of this syntax. a critical part of this syntax.
记住,`ngIf`前面的星号(`*`)是语法中的重要组成部分。
:marked :marked
When there is no `selectedHero`, the `ngIf` directive removes the hero detail HTML from the DOM. 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. 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 When the user picks a hero, `selectedHero` becomes "truthy" and
`ngIf` puts the hero detail content into the DOM and evaluates the nested bindings. `ngIf` puts the hero detail content into the DOM and evaluates the nested bindings.
当用户选取了一个英雄,`selectedHero`变成了真值,于是`ngIf`把“英雄详情”加回DOM中并且计算它所嵌套的各种绑定。
.l-sub-section .l-sub-section
:marked :marked
`ngIf` and `ngFor` are called “structural directives” because they can change the `ngIf` and `ngFor` are called “structural directives” because they can change the
structure of portions of the DOM. structure of portions of the DOM.
In other words, they give structure to the way Angular displays content in 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 Learn more about `ngIf`, `ngFor` and other structural directives in the
[Structural Directives](../guide/structural-directives.html) and [Structural Directives](../guide/structural-directives.html) and
[Template Syntax](../guide/template-syntax.html#directives) chapters. [Template Syntax](../guide/template-syntax.html#directives) chapters.
要了解更多`ngIf``ngFor`和其它结构型指令,请参阅:
[结构型指令](../guide/structural-directives.html)和
[模板语法](../guide/template-syntax.html#directives)章节。
:marked :marked
The browser refreshes and we see the list of heroes but not the selected hero detail. 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. 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. When we click on a hero in the list, the selected hero displays in the hero details.
Everything is working as we expect. Everything is working as we expect.
浏览器刷新了,我们看到了一个英雄列表,但是还没有选中的英雄详情。
当`selectedHero`是`undefined`时,`ngIf`会保证英雄详情不出现在DOM中。
当我们从列表中点击一个英雄时,选中的英雄被显示在英雄详情里。
正如我们所预期的那样。
### Styling the selection ### Styling the selection
### 给所选英雄添加样式
We see the selected hero in the details area below but we cant quickly locate that hero in the list above. We see the selected hero in the details area below but we cant 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. 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, 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. we can make it pop out visually by giving it a subtle background color as shown here.
我们在下面的详情区看到了选中的英雄,但是我们还是没法在上面的列表区快速的找到这位英雄。
通过把CSS类`selected`添加到主列表的`<li>`元素上,我们可以解决这个问题。
比如当我们在列表区选中了Magneta时我们可以通过设置一个轻微的背景色来让他略显突出。
figure.image-display figure.image-display
img(src='/resources/images/devguide/toh/heroes-list-selected.png' alt="Selected hero") img(src='/resources/images/devguide/toh/heroes-list-selected.png' alt="选中的英雄")
:marked :marked
Well 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`. Well 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. The key is the name of the CSS class (`selected`). The value is `true` if the two heroes match and `false` otherwise.
Were saying “*apply the `selected` class if the heroes match, remove it if they dont*”. Were saying “*apply the `selected` class if the heroes match, remove it if they dont*”.
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'class-selected-1', 'app.component.ts (Setting the CSS class)')(format=".")
关键是CSS类的名字`selected`。当两位英雄一致时,它为`true`,否则为`false`。
也就是说:“*当两位英雄匹配时,应用上`selected`类,否则不应用*”。
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'class-selected-1', 'app.component.ts (设置CSS类)')(format=".")
:marked :marked
Notice in the template that the `class.selected` is surrounded in square brackets (`[]`). 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 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`. 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=".") +makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'class-selected-2', 'app.component.ts (Styling each hero)')(format=".")
.l-sub-section .l-sub-section
@ -298,33 +439,56 @@ code-example(format="." language="bash").
Learn more about [Property Binding](../guide/template-syntax.html#property-binding) Learn more about [Property Binding](../guide/template-syntax.html#property-binding)
in the Template Syntax chapter. in the Template Syntax chapter.
学习关于[属性绑定](../guide/template-syntax.html#property-binding)
的更多知识,参见“模板语法”一章。
:marked :marked
The browser reloads our app. The browser reloads our app.
We select the hero Magneta and the selection is clearly identified by the background color. We select the hero Magneta and the selection is clearly identified by the background color.
浏览器重新加载了你的应用。
我们选中英雄Magneta于是他通过背景色的变化被清晰的标记了出来。
figure.image-display figure.image-display
img(src='/resources/images/devguide/toh/heroes-list-1.png' alt="Output of heroes list app") img(src='/resources/images/devguide/toh/heroes-list-1.png' alt="英雄列表应用的输出")
:marked :marked
We select a different hero and the tell-tale color switches to that hero. 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: 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') +makeExample('toh-2/ts/app/app.component.ts', 'pt2', 'app.component.ts')
.l-main-section .l-main-section
:marked :marked
## The Road Weve Travelled ## The Road Weve Travelled
## 已走的路
Heres what we achieved in this chapter: Heres what we achieved in this chapter:
在本章中,我们达成了这些:
* Our Tour of Heroes now displays a list of selectable heroes * Our Tour of Heroes now displays a list of selectable heroes
* 我们的《英雄之旅》现在显示一个可选英雄的列表
* We added the ability to select a hero and show the heros details * We added the ability to select a hero and show the heros details
* 我们添加了选择英雄的能力,并且会显示这个英雄的详情
* We learned how to use the built-in directives `ngIf` and `ngFor` in a components template * We learned how to use the built-in directives `ngIf` and `ngFor` in a components template
* 我们学会了如何在组件模板中使用内置的`ngIf`和`ngFor`指令
[Run the live example for part 2](/resources/live-examples/toh-2/ts/plnkr.html) [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 ### The Road Ahead
### 前方的路
Our Tour of Heroes has grown, but its far from complete. Our Tour of Heroes has grown, but its far from complete.
We can't put the entire app into a single component. 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 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). as we learn in the [next chapter](toh-pt3.html).
我们的《英雄之旅》长大了,但还远远不够完善。
我们显然不能把整个应用都放进一个组件中。
我们需要把它拆分成一系列子组件,然后教它们协同工作 ——
就像我们[下一章](toh-pt3.html)学到的一样。