Polish top pt2

This commit is contained in:
Yang Lin 2016-11-06 04:14:42 +08:00 committed by 雪狼
parent 14eed65c12
commit 1586163b0d

View File

@ -9,7 +9,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></live-example> for this part. Run the <live-example></live-example> for this part.
@ -96,7 +96,7 @@ code-example(language="bash").
Lets create a public property in `AppComponent` that exposes the heroes for binding. Lets create a public property in `AppComponent` that exposes the heroes for binding.
我们在`AppComponent`上创建一个公属性,用来暴露这些英雄,以供绑定。 我们在`AppComponent`上创建一个公属性,用来暴露这些英雄,以供绑定。
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'hero-array-1', 'app.component.ts (hero array property)') +makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'hero-array-1', 'app.component.ts (hero array property)')
@ -114,7 +114,7 @@ code-example(language="bash").
我们已经把英雄列表定义在了这个组件类中。 我们已经把英雄列表定义在了这个组件类中。
但显然,我们最终还是得从一个数据服务中获取这些英雄。 但显然,我们最终还是得从一个数据服务中获取这些英雄。
正因如此,我们从一开始就要有意识的把英雄数据隔离到一个类中来实现。 正因如此,一开始就应该把英雄数据隔离到一个类中来实现。
:marked :marked
### Displaying heroes in a template ### Displaying heroes in a template
@ -226,13 +226,13 @@ code-example(language="bash").
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.
其实有很多种写法!我们可以像这里这样把模板内联进去,或者把模板移到单独的文件中 —— 这样能让编写组件变得更容易。后面的章节中我们会尝试使用独立模板,但现在我们先不管它。 这里有很多种样式!我们可以像上面那样把它们内联在组件中,或者把样式移到单独的文件中 —— 这样能让编写组件变得更容易。我们会后面的章节中使用独立样式文件,现在我们先不管它。
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中。 上面的例子中,这些样式只会作用于`AppComponent`组件而不会“泄露”到外部HTML中。
Our template for displaying the heroes should now look like this: Our template for displaying the heroes should now look like this:
@ -252,15 +252,15 @@ code-example(language="bash").
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布局模式通常被称为“主从”。 这种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事件上。 我们通过组件中的一个`selectedHero`属性来连接主从视图它被绑定到了click事件上。
### Click event ### Click event
@ -326,7 +326,7 @@ code-example(language="bash").
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`属性。 在`AppComponent`,我们不再需要一个固定的`hero`属性。
那就直接把它改为`selectedHero`属性。 那就直接把它改为`selectedHero`属性。
+makeExample('toh-2/ts/app/app.component.ts', 'selected-hero', 'app.component.ts (selectedHero)') +makeExample('toh-2/ts/app/app.component.ts', 'selected-hero', 'app.component.ts (selectedHero)')
@ -339,7 +339,7 @@ code-example(language="bash").
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`属性。 现在,**添加一个`onSelect`方法**用于将用户点击的英雄赋给`selectedHero`属性。
+makeExample('toh-2/ts/app/app.component.ts', 'on-select', 'app.component.ts (onSelect)') +makeExample('toh-2/ts/app/app.component.ts', 'on-select', 'app.component.ts (onSelect)')
@ -349,14 +349,14 @@ code-example(language="bash").
Lets fix the template to bind to the new `selectedHero` property. Lets fix the template to bind to the new `selectedHero` property.
我们将把所选英雄的详细信息显示在模板中。目前,它仍然引用的是以前的`hero`属性。 我们将把所选英雄的详细信息显示在模板中。目前,它仍然引用的是以前的`hero`属性。
我们这就修改模板,让它绑定到新的`selectedHero`属性上去 我们这就修改模板,让它绑定到新的`selectedHero`属性。
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'selectedHero-details', 'app.component.ts (template excerpt)') +makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'selectedHero-details', 'app.component.ts (template excerpt)')
:marked :marked
### Hide the empty detail with ngIf ### Hide the empty detail with ngIf
### 用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`.
@ -373,17 +373,18 @@ code-example(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`。 别忘了我们要在模板中显示的是`selectedHero.name`。
显然这个name属性是不存在的因为`selectedHero`本身还是`undefined`呢。 显然这个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中 —— 直到有英雄被选中。 要处理这个问题我们可以先让英雄详情不要出现在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`内置指令,然后把`ngIf`的值设置为本组件的`selectedHero`属性。 我们把模板中的“英雄详情”内容区用放在一个`<div>`中。
然后往上添加一个`ngIf`内置指令,然后把`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)')
@ -403,7 +404,7 @@ code-example(language="bash").
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中并且计算它所嵌套的各种绑定。 当用户选取了一个英雄,`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
@ -467,7 +468,7 @@ code-example(language="bash").
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`是括在一对方括号中的。 注意,模板中的`class.selected`是括在一对方括号中的。
这就是“属性绑定”的语法,一种从数据源(即`hero === selectedHero`表达式)到`class`属性的单向数据流。 这就是“属性绑定”的语法,一种从数据源(即`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=".")
@ -483,7 +484,7 @@ code-example(language="bash").
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于是它通过背景色的变化被清晰的标记了出来。 我们选中英雄Magneta于是它通过背景色的变化被清晰的标记了出来。
figure.image-display figure.image-display