翻译完了toh-pt3的新增内容

This commit is contained in:
Zhicheng Wang 2017-04-16 21:57:26 +08:00
parent 4c3547f73a
commit e5c750301c
5 changed files with 150 additions and 3 deletions

View File

@ -54,10 +54,13 @@ code-example(language="sh" class="code-shell").
:marked :marked
This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes. This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes.
The command simultaneously launches the app in a browser and refreshes the browser when the code changes. The command simultaneously launches the app in a browser and refreshes the browser when the code changes.
这个命令会在"监听"模式下运行TypeScript编译器当代码变化时它会自动重新编译。
同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。
You can keep building the Tour of Heroes without pausing to recompile or refresh the browser. You can keep building the Tour of Heroes without pausing to recompile or refresh the browser.
这个命令会在我们构建《英雄指南》的时候让应用得以持续运行 在后续构建《英雄指南》过程中,应用能持续运行,而不用中断服务来编译或刷新浏览器
.l-main-section .l-main-section
:marked :marked

View File

@ -65,56 +65,102 @@ include ../_util-fns
Add a file named `hero-detail.component.ts` to the `app/` folder. Add a file named `hero-detail.component.ts` to the `app/` folder.
This file will hold the new `HeroDetailComponent`. This file will hold the new `HeroDetailComponent`.
往`app/`文件夹下添加一个名叫`hero-detail.component.ts`的文件。这个文件中会存放这个新的`HeroDetailComponent`。
The file and component names follow the standard described in the Angular The file and component names follow the standard described in the Angular
[style guide](../guide/style-guide.html#naming). [style guide](../guide/style-guide.html#naming).
文件名和组件名遵循[风格指南](../guide/style-guide.html#naming)中的标准方式。
* The component _class_ name should be written in _upper camel case_ and end in the word "Component". * The component _class_ name should be written in _upper camel case_ and end in the word "Component".
The hero detail component class is `HeroDetailComponent`. The hero detail component class is `HeroDetailComponent`.
组件的类名应该是*大驼峰形式*,并且以`Component`结尾。
因此英雄详情组件的类名是`HeroDetailComponent`。
* The component _file_ name should be spelled in [_lower dash case_](../guide/glossary.html#dash-case), * The component _file_ name should be spelled in [_lower dash case_](../guide/glossary.html#dash-case),
each word separated by dashes, and end in `.component.ts`. each word separated by dashes, and end in `.component.ts`.
The `HeroDetailComponent` class goes in the `hero-detail.component.ts` file. The `HeroDetailComponent` class goes in the `hero-detail.component.ts` file.
组件的文件名应该是[小写中线形式](../guide/glossary.html#dash-case),每个单词之间用中线分隔,并且以`.component.ts`结尾。
因此`HeroDetailComponent`类应该放在`hero-detail.component.ts`文件中。
Start writing the `HeroDetailComponent` as follows: Start writing the `HeroDetailComponent` as follows:
`HeroDetailComponent`的代码如下:
+makeExample('toh-3/ts/app/hero-detail.component.1.ts', 'v1', 'app/hero-detail.component.ts (initial version)')(format=".") +makeExample('toh-3/ts/app/hero-detail.component.1.ts', 'v1', 'app/hero-detail.component.ts (initial version)')(format=".")
a#selector a#selector
:marked :marked
To define a component, you always import the `Component` symbol. To define a component, you always import the `Component` symbol.
要定义一个组件,我们总是要先导入符号`Component`。
The `@Component` decorator provides the Angular metadata for the component. The `@Component` decorator provides the Angular metadata for the component.
The CSS selector name, `hero-detail`, will match the element tag The CSS selector name, `hero-detail`, will match the element tag
that identifies this component within a parent component's template. that identifies this component within a parent component's template.
[Near the end of this tutorial page](#add-hero-detail "Add the HeroDetailComponent to the AppComponent"), [Near the end of this tutorial page](#add-hero-detail "Add the HeroDetailComponent to the AppComponent"),
you'll add a `<hero-detail>` element to the `AppComponent` template. you'll add a `<hero-detail>` element to the `AppComponent` template.
`@Component`装饰器为组件提供了Angular元数据。
CSS选择器的名字`hero-detail`会匹配元素的标签名,用于在父组件的模板中标记出当前组件的位置。
[本章的最后](#add-hero-detail "Add the HeroDetailComponent to the AppComponent"),我们会把`<hero-detail>`添加到`AppComponent`的模板中。
Always `export` the component class because you'll always `import` it elsewhere. Always `export` the component class because you'll always `import` it elsewhere.
总是`export`这个组件类,因为你必然会在别处`import`它。
:marked :marked
### Hero detail template ### Hero detail template
### 英雄详情的模板
To move the hero detail view to the `HeroDetailComponent`, To move the hero detail view to the `HeroDetailComponent`,
cut the hero detail _content_ from the bottom of the `AppComponent` template cut the hero detail _content_ from the bottom of the `AppComponent` template
and paste it into a new `template` property in the `@Component` metadata. and paste it into a new `template` property in the `@Component` metadata.
要把英雄详情的视图移入`HeroDetailComponent`,只要把英雄详情的 *内容* 从`AppComponent`模板的底部剪切出来,
粘贴到`@Component`元数据的`template`属性中就可以了。
The `HeroDetailComponent` has a _hero_, not a _selected hero_. The `HeroDetailComponent` has a _hero_, not a _selected hero_.
Replace the word, "selectedHero", with the word, "hero", everywhere in the template. Replace the word, "selectedHero", with the word, "hero", everywhere in the template.
When you're done, the new template should look like this: When you're done, the new template should look like this:
`HeroDetailComponent`有一个 `hero`属性,而不再是`selectedHero`。
所以我们也要在模板中把所有的`selectedHero`替换为`hero`。
这些完成之后,新的模板是这样的:
+makeExample('toh-3/ts/src/app/hero-detail.component.ts', 'template', 'src/app/hero-detail.component.ts (template)')(format=".") +makeExample('toh-3/ts/src/app/hero-detail.component.ts', 'template', 'src/app/hero-detail.component.ts (template)')(format=".")
:marked :marked
### Add the *hero* property ### Add the *hero* property
### 添加`hero`属性
The `HeroDetailComponent` template binds to the component's `hero` property. The `HeroDetailComponent` template binds to the component's `hero` property.
Add that property to the `HeroDetailComponent` class like this: Add that property to the `HeroDetailComponent` class like this:
`HeroDetailComponent`模板绑定到了该组件的`hero`属性上。
把这个属性添加到`HeroDetailComponent`类上,就像这样:
+makeExample('toh-3/ts/app/hero-detail.component.1.ts', 'hero', 'src/app/hero-detail.component.ts (hero property)') +makeExample('toh-3/ts/app/hero-detail.component.1.ts', 'hero', 'src/app/hero-detail.component.ts (hero property)')
:marked :marked
The `hero` property is typed as an instance of `Hero`. The `hero` property is typed as an instance of `Hero`.
The `Hero` class is still in the `app.component.ts` file. The `Hero` class is still in the `app.component.ts` file.
Now there are two components that need to reference the `Hero` class. Now there are two components that need to reference the `Hero` class.
The Angular [style guide](../guide/style-guide.html#rule-of-one "Style guide: rule of one") recommends one class per file anyway. The Angular [style guide](../guide/style-guide.html#rule-of-one "Style guide: rule of one") recommends one class per file anyway.
`hero`属性的类型是`Hero`。
`Hero`类仍然在`app.component.ts`文件中。
现在,有两个组件需要`Hero`类的引用。
而Angular[风格指南](../guide/style-guide.html#rule-of-one "Style guide: rule of one")建议每个文件中只有一个类。
Move the `Hero` class from `app.component.ts` to its own `hero.ts` file. Move the `Hero` class from `app.component.ts` to its own `hero.ts` file.
因此我们要把`Hero`类从`app.component.ts`移到它自己的`hero.ts`文件中:
+makeExample('toh-3/ts/src/app/hero.ts', '', 'src/app/hero.ts')(format=".") +makeExample('toh-3/ts/src/app/hero.ts', '', 'src/app/hero.ts')(format=".")
@ -122,6 +168,9 @@ a#selector
Now that the `Hero` class is in its own file, the `AppComponent` and the `HeroDetailComponent` have to import it. Now that the `Hero` class is in its own file, the `AppComponent` and the `HeroDetailComponent` have to import it.
Add the following `import` statement near the top of _both_ the `app.component.ts` and the `hero-detail.component.ts` files. Add the following `import` statement near the top of _both_ the `app.component.ts` and the `hero-detail.component.ts` files.
现在,`Hero`类有了自己的文件,`AppComponent` 和 `HeroDetailComponent` 就要`import`它了。
把下列`import`语句添加到`app.component.ts`和`hero-detail.component.ts`文件的顶部。
+makeExample('toh-3/ts/app/hero-detail.component.1.ts', 'hero-import') +makeExample('toh-3/ts/app/hero-detail.component.1.ts', 'hero-import')
:marked :marked
@ -134,19 +183,33 @@ a#selector
by binding its `selectedHero` to the `hero` property of the `HeroDetailComponent`. by binding its `selectedHero` to the `hero` property of the `HeroDetailComponent`.
The binding will look like this: The binding will look like this:
[在本章稍后的部分](#add-hero-detail "Add the HeroDetailComponent to the AppComponent")
父组件`AppComponent`会告诉子组件`HeroDetailComponent`要显示哪个英雄,
告诉的方法是把它的`selectedHero`属性绑定到`HeroDetailComponent`的`hero`属性上。
这种绑定是这样的:
+makeExample('toh-3/ts/app/app.component.1.html', 'hero-detail-binding')(format='.') +makeExample('toh-3/ts/app/app.component.1.html', 'hero-detail-binding')(format='.')
:marked :marked
Putting square brackets around the `hero` property, to the left of the equal sign (=), Putting square brackets around the `hero` property, to the left of the equal sign (=),
makes it the *target* of a property binding expression. makes it the *target* of a property binding expression.
You must declare a *target* binding property to be an *input* property. You must declare a *target* binding property to be an *input* property.
Otherwise, Angular rejects the binding and throws an error. Otherwise, Angular rejects the binding and throws an error.
在等号的左边,是方括号围绕的`hero`属性,这表示它是属性绑定表达式的*目标*。
我们要绑定到的*目标*属性必须是一个*输入*属性否则Angular会拒绝绑定并抛出一个错误。
First, amend the `@angular/core` import statement to include the `Input` symbol. First, amend the `@angular/core` import statement to include the `Input` symbol.
首先,修改`@angular/core`导入语句,使其包含符号`Input`。
+makeExample('toh-3/ts/src/app/hero-detail.component.ts', 'import-input', 'src/app/hero-detail.component.ts (excerpt)')(format='.') +makeExample('toh-3/ts/src/app/hero-detail.component.ts', 'import-input', 'src/app/hero-detail.component.ts (excerpt)')(format='.')
:marked :marked
Then declare that `hero` is an *input* property by Then declare that `hero` is an *input* property by
preceding it with the `@Input` decorator that you imported earlier. preceding it with the `@Input` decorator that you imported earlier.
然后,通过在`hero`属性前面加上`@Input`装饰器,来表明它是一个输入属性。
+makeExample('toh-3/ts/src/app/hero-detail.component.ts', 'hero', 'src/app/hero-detail.component.ts (excerpt)')(format='.') +makeExample('toh-3/ts/src/app/hero-detail.component.ts', 'hero', 'src/app/hero-detail.component.ts (excerpt)')(format='.')
@ -154,87 +217,153 @@ a#selector
:marked :marked
Read more about _input_ properties in the Read more about _input_ properties in the
[Attribute Directives](../guide/attribute-directives.html#why-input) page. [Attribute Directives](../guide/attribute-directives.html#why-input) page.
要了解*输入属性*的更多知识,参见[属性型指令](../guide/attribute-directives.html#why-input)页。
:marked :marked
That's it. The `hero` property is the only thing in the `HeroDetailComponent` class. That's it. The `hero` property is the only thing in the `HeroDetailComponent` class.
现在,`hero`属性是`HeroDetailComponent`类中唯一的东西。
+makeExample('toh-3/ts/src/app/hero-detail.component.ts', 'class')(format='.') +makeExample('toh-3/ts/src/app/hero-detail.component.ts', 'class')(format='.')
:marked :marked
All it does is receive a hero object through its `hero` input property and then bind to that property with its template. All it does is receive a hero object through its `hero` input property and then bind to that property with its template.
它所做的一切就是通过它的输入属性`hero`接收一个英雄对象,然后把这个属性绑定到自己的模板中。
Here's the complete `HeroDetailComponent`. Here's the complete `HeroDetailComponent`.
下面是完整的`HeroDetailComponent`
+makeExample('toh-3/ts/src/app/hero-detail.component.ts', '', 'src/app/hero-detail.component.ts') +makeExample('toh-3/ts/src/app/hero-detail.component.ts', '', 'src/app/hero-detail.component.ts')
.l-main-section .l-main-section
:marked :marked
## Declare _HeroDetailComponent_ in the _AppModule_ ## Declare _HeroDetailComponent_ in the _AppModule_
## 在`AppModule`中声明`HeroDetailComponent`
Every component must be declared in one&mdash;and only one&mdash;Angular module. Every component must be declared in one&mdash;and only one&mdash;Angular module.
每个组件都必须在一个且只有一个Angular模块中声明。
Open `app.module.ts` in your editor and import the `HeroDetailComponent` so you can refer to it. Open `app.module.ts` in your editor and import the `HeroDetailComponent` so you can refer to it.
打开`app.module.ts`并且导入`HeroDetailComponent`,以便我们可以引用它。
+makeExample('toh-3/ts/src/app/app.module.ts', 'hero-detail-import', 'src/app/app.module.ts') +makeExample('toh-3/ts/src/app/app.module.ts', 'hero-detail-import', 'src/app/app.module.ts')
:marked :marked
Add `HeroDetailComponent` to the module's `declarations` array. Add `HeroDetailComponent` to the module's `declarations` array.
把`HeroDetailComponent`添加到该模块的`declarations`数组中。
+makeExample('toh-3/ts/src/app/app.module.ts', 'declarations', 'src/app/app.module.ts')(format='.') +makeExample('toh-3/ts/src/app/app.module.ts', 'declarations', 'src/app/app.module.ts')(format='.')
:marked :marked
In general, the `declarations` array contains a list of application components, pipes, and directives that belong to the module. In general, the `declarations` array contains a list of application components, pipes, and directives that belong to the module.
A component must be declared in a module before other components can reference it. A component must be declared in a module before other components can reference it.
This module declares only the two application components, `AppComponent` and `HeroDetailComponent`. This module declares only the two application components, `AppComponent` and `HeroDetailComponent`.
通常,`declarations`数组包含应用中属于该模块的组件、管道和指令的列表。
组件在被其它组件引用之前必须先在一个模块中声明过。
这个模块只声明了两个组件:`AppComponent` 和 `HeroDetailComponent`。
.l-sub-section .l-sub-section
:marked :marked
Read more about Angular modules in the [NgModules](../guide/ngmodule.html "Angular Modules (NgModule)") guide. Read more about Angular modules in the [NgModules](../guide/ngmodule.html "Angular Modules (NgModule)") guide.
要了解关于Angular模块的更多知识参见[Angular模块](../guide/ngmodule.html "Angular Modules (NgModule)")页。
a#add-hero-detail a#add-hero-detail
.l-main-section .l-main-section
:marked :marked
## Add the _HeroDetailComponent_ to the _AppComponent_ ## Add the _HeroDetailComponent_ to the _AppComponent_
## 把`HeroDetailComponent`添加到`AppComponent`中
:marked :marked
The `AppComponent` is still a master/detail view. The `AppComponent` is still a master/detail view.
It used to display the hero details on its own, before you cut out that portion of the template. It used to display the hero details on its own, before you cut out that portion of the template.
Now it will delegate to the `HeroDetailComponent`. Now it will delegate to the `HeroDetailComponent`.
`AppComponent`仍然是主从视图。
在我们剪切模板之前,它自己显示英雄的详情。
现在,它委托给了`HeroDetailComponent`。
Recall that `hero-detail` is the CSS [`selector`](#selector "HeroDetailComponent selector") Recall that `hero-detail` is the CSS [`selector`](#selector "HeroDetailComponent selector")
in the `HeroDetailComponent` metadata. in the `HeroDetailComponent` metadata.
That's the tag name of the element that represents the `HeroDetailComponent`. That's the tag name of the element that represents the `HeroDetailComponent`.
回想一下,`hero-detail`正是`HeroDetailComponent`元数据中使用的 CSS [`selector`](#selector "HeroDetailComponent selector")
它是一个HTML元素的标签名用于表示`HeroDetailComponent`。
Add a `<hero-detail>` element near the bottom of the `AppComponent` template, Add a `<hero-detail>` element near the bottom of the `AppComponent` template,
where the hero detail view used to be. where the hero detail view used to be.
把`<hero-detail>`元素添加到`AppComponent`模板的底部,那里就是英雄详情视图所在的位置。
Coordinate the master `AppComponent` with the `HeroDetailComponent` Coordinate the master `AppComponent` with the `HeroDetailComponent`
by binding the `selectedHero` property of the `AppComponent` by binding the `selectedHero` property of the `AppComponent`
to the `hero` property of the `HeroDetailComponent`. to the `hero` property of the `HeroDetailComponent`.
协调主视图`AppComponent`与`HeroDetailComponent`的方式是把`AppComponent`的`selectedHero`属性绑定到`HeroDetailComponent`的`hero`属性上。
+makeExample('toh-3/ts/app/app.component.1.html', 'hero-detail-binding', 'app.component.ts (excerpt)')(format='.') +makeExample('toh-3/ts/app/app.component.1.html', 'hero-detail-binding', 'app.component.ts (excerpt)')(format='.')
:marked :marked
Now every time the `selectedHero` changes, the `HeroDetailComponent` gets a new hero to display. Now every time the `selectedHero` changes, the `HeroDetailComponent` gets a new hero to display.
每当`selectedHero`变化时,`HeroDetailComponent`就会显示一个新的英雄。
The revised `AppComponent` template should look like this: The revised `AppComponent` template should look like this:
修改后的`AppComponent`模板是这样的:
+makeExample('toh-3/ts/src/app/app.component.ts', 'hero-detail-template', 'app.component.ts (excerpt)')(format='.') +makeExample('toh-3/ts/src/app/app.component.ts', 'hero-detail-template', 'app.component.ts (excerpt)')(format='.')
.l-main-section .l-main-section
:marked :marked
## What changed? ## What changed?
## 有哪些变化?
As [before](./toh-pt2.html), whenever a user clicks on a hero name, As [before](./toh-pt2.html), whenever a user clicks on a hero name,
the hero detail appears below the hero list. the hero detail appears below the hero list.
But now the `HeroDetailView` is presenting those details. But now the `HeroDetailView` is presenting those details.
仍然像[以前](./toh-pt2.html)一样,一旦用户点击了英雄的名字,英雄详情就会显示在英雄列表的下方。
不过现在改用`HeroDetailView`来表示英雄详情了。
Refactoring the original `AppComponent` into two components yields benefits, both now and in the future: Refactoring the original `AppComponent` into two components yields benefits, both now and in the future:
我们把原来的`AppComponent`重构成了两个组件具有一些显著优点,无论是现在还是未来:
1. You simplified the `AppComponent` by reducing its responsibilities. 1. You simplified the `AppComponent` by reducing its responsibilities.
通过缩减`AppComponent`的职责,我们简化了它。
1. You can evolve the `HeroDetailComponent` into a rich hero editor 1. You can evolve the `HeroDetailComponent` into a rich hero editor
without touching the parent `AppComponent`. without touching the parent `AppComponent`.
我们将来可以把`HeroDetailComponent`改进为功能更丰富的英雄编辑器,而不用动`AppComponent`。
1. You can evolve the `AppComponent` without touching the hero detail view. 1. You can evolve the `AppComponent` without touching the hero detail view.
同样,我们也可以改进`AppComponent`而不用动英雄详情视图。
1. You can re-use the `HeroDetailComponent` in the template of some future parent component. 1. You can re-use the `HeroDetailComponent` in the template of some future parent component.
我们可以在未来的其它父组件的模板中复用`HeroDetailComponent`。
### Review the app structure ### Review the app structure
### 审视本应用的代码结构
Verify that you have the following structure: Verify that you have the following structure:
验证它是否已经有了如下结构:
.filetree .filetree
.file angular-tour-of-heroes .file angular-tour-of-heroes
@ -298,7 +427,7 @@ a#add-hero-detail
* You learned to bind a parent component to a child component. * You learned to bind a parent component to a child component.
我们学会了把父组件绑定到子组件。 我们学会了把父组件绑定到子组件。
Your app should look like this <live-example></live-example>. Your app should look like this <live-example></live-example>.

View File

@ -61,8 +61,13 @@ code-example(language="sh" class="code-shell").
:marked :marked
This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes. This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes.
The command simultaneously launches the app in a browser and refreshes the browser when the code changes. The command simultaneously launches the app in a browser and refreshes the browser when the code changes.
这个命令会在"监听"模式下运行TypeScript编译器当代码变化时它会自动重新编译。
同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。
You can keep building the Tour of Heroes without pausing to recompile or refresh the browser. You can keep building the Tour of Heroes without pausing to recompile or refresh the browser.
在后续构建《英雄指南》过程中,应用能持续运行,而不用中断服务来编译或刷新浏览器。
## Creating a hero service ## Creating a hero service

View File

@ -95,9 +95,14 @@ code-example(language="sh" class="code-shell").
:marked :marked
This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes. This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes.
The command simultaneously launches the app in a browser and refreshes the browser when the code changes. The command simultaneously launches the app in a browser and refreshes the browser when the code changes.
这个命令会在"监听"模式下运行TypeScript编译器当代码变化时它会自动重新编译。
同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。
:marked :marked
You can keep building the Tour of Heroes without pausing to recompile or refresh the browser. You can keep building the Tour of Heroes without pausing to recompile or refresh the browser.
在后续构建《英雄指南》过程中,应用能持续运行,而不用中断服务来编译或刷新浏览器。
## Action plan ## Action plan

View File

@ -53,9 +53,14 @@ code-example(language="sh" class="code-shell").
:marked :marked
This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes. This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes.
The command simultaneously launches the app in a browser and refreshes the browser when the code changes. The command simultaneously launches the app in a browser and refreshes the browser when the code changes.
这个命令会在"监听"模式下运行TypeScript编译器当代码变化时它会自动重新编译。
同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。
:marked :marked
You can keep building the Tour of Heroes without pausing to recompile or refresh the browser. You can keep building the Tour of Heroes without pausing to recompile or refresh the browser.
在后续构建《英雄指南》过程中,应用能持续运行,而不用中断服务来编译或刷新浏览器。
.l-main-section#http-providers .l-main-section#http-providers
h1 Providing HTTP Services h1 Providing HTTP Services
@ -97,7 +102,7 @@ h1 提供 HTTP 服务
:marked :marked
Notice that you also supply `HttpModule` as part of the *imports* array in root NgModule `AppModule`. Notice that you also supply `HttpModule` as part of the *imports* array in root NgModule `AppModule`.
注意,现在`HttpModule`已经是根模块`AppModule`的`imports`数组的一部分了。 注意,现在`HttpModule`已经是根模块`AppModule`的`imports`数组的一部分了。
.l-main-section .l-main-section
:marked :marked