This commit is contained in:
Rex 2016-05-11 17:04:34 +01:00
commit 55722de87a
14 changed files with 160 additions and 163 deletions

View File

@ -105,7 +105,7 @@ figure.image-display
Use an input property setter to intercept and act upon a value from the parent.
使用一个Input属性setter在父级监听子级属性,并对属性值变化采取行动。
使用一个Input属性setter在父级拦截子级属性,并对属性值变化采取行动。
The setter of the `name` input property in the child `NameChildComponent`
trims the whitespace from a name and replaces an empty value with default text.
@ -152,7 +152,7 @@ figure.image-display
:marked
May prefer this approach to the property setter when watching multiple, interacting input properties.
当监多个互动Input属性的时候本方法比属性setter更合适。
当监多个互动Input属性的时候本方法比属性setter更合适。
Learn about `ngOnChanges` in the [LifeCycle Hooks](../guide/lifecycle-hooks.html) chapter.

View File

@ -405,7 +405,7 @@ include _util-fns
is when we [bootstrap](#bootstrap) the application.
There are other opportunities to register as well.
Angular会为每个注册器注册很多自己的内Provider。我们也可以注册自己的Provider。通常注册Provider的最佳时间是在应用程序开始[引导](#bootstrap)的时候。
Angular会为每个注册器注册很多自己的内Provider。我们也可以注册自己的Provider。通常注册Provider的最佳时间是在应用程序开始[引导](#bootstrap)的时候。
当然我们也有其它很多机会注册Provider。
Learn more in the [Dependency Injection](guide/dependency-injection.html) chapter.
@ -567,7 +567,7 @@ include _util-fns
before it is assigned to an element property
or displayed between element tags as in this example.
[属性数据绑定](#data-binding) 的式之一:位于双大括号中的[模板表达式](#template-expression)会被渲染成文本。在被赋值给元素属性或者显示在元素标中之前,这些文本可能先与周边的文本合并,参见下面的例子。
[属性数据绑定](#data-binding) 的式之一:位于双大括号中的[模板表达式](#template-expression)会被渲染成文本。在被赋值给元素属性或者显示在元素标中之前,这些文本可能先与周边的文本合并,参见下面的例子。
code-example(language="html" escape="html").
<label>My current hero is {{hero.name}}</label>
@ -597,7 +597,7 @@ include _util-fns
This form is also known as [dash-case](#dash-case).
这种式也叫[中线命名法](#dash-case)。
这种式也叫[中线命名法](#dash-case)。
<a id="L"></a>
.l-main-section
@ -834,7 +834,7 @@ include _util-fns
It likely has anchor tags or buttons with `RouterLink` directives that users can click to navigate.
它很大可能还会有一些有`RouterLink`指令的锚标记或按钮,用户可以用来点击导航。
它很大可能还会有一些有`RouterLink`指令的a标签或按钮,用户可以用来点击导航。
<a id="S"></a>
.l-main-section

View File

@ -568,7 +568,7 @@ figure
We see two built-in structural directives at play in our [example](#template) template:
我们在[范例](#template)模板中会看到两个内的结构型指令。
我们在[范例](#template)模板中会看到两个内的结构型指令。
+makeExample('architecture/ts/app/hero-list.component.1.html', 'structural')(format=".")
:marked
* [`*ngFor`](displaying-data.html#ngFor) tells Angular to stamp out one `<div>` per hero in the `heroes` list.

View File

@ -118,7 +118,7 @@ include ../_quickstart_repo
We're ready to see changes in a running app by firing up the npm script that both compiles and serves our applications
while watching for changes.
通过运行npm脚本它能编译并启动一个能监变化的服务器),我们能看到运行中的应用发生的变化。
通过运行npm脚本它能编译并启动一个能监变化的服务器),我们能看到运行中的应用发生的变化。
code-example(format="").
npm start
:marked

View File

@ -948,7 +948,7 @@ figure.image-display
control* is valid.
`NgForm`指令使用额外的特性扩充了`form`元素。
它保存我们通过`ngControl`属性为各个元素创建的控件类,并且监它们的属性变化,包括有效性。
它保存我们通过`ngControl`属性为各个元素创建的控件类,并且监它们的属性变化,包括有效性。
它还有自己的`valid`属性,只有当 *每一个被包含的控件* 都有效时,它才有效。
:marked

View File

@ -347,11 +347,7 @@ a(href="#toc") 回到顶部
.s-rule.do
:marked
**Do** use consistent names for all assets named after what they represent.
<<<<<<< HEAD
**做** 为所有东西使用统一的命名:以它们所代表的东西命名
=======
**做** 为所有财产的使用统一的命名:以它们所代表的东西命名
>>>>>>> f0e75413c854b8966c506c7c351339c9f5e98512
.s-rule.do
:marked

View File

@ -33,7 +33,7 @@ include ../_util-fns
* [Two-way data binding with `NgModel`](#ngModel)
* [使用`NgModel`进行双向数据绑定](#ngModel)
* [Built-in directives](#directives)
* [内指令](#directives)
* [内指令](#directives)
* [NgClass](#ngClass)
* [NgStyle](#ngStyle)
* [NgIf](#ngIf)
@ -1471,7 +1471,7 @@ code-example(format="", language="html").
:marked
Alternatively, we can use the canonical prefix form:
另外,我们也可以使用规范前缀式:
另外,我们也可以使用规范前缀式:
// #enddocregion ngModel-2
+makeExample('template-syntax/ts/app/app.component.html', 'NgModel-2')(format=".")
// #docregion ngModel-3
@ -2019,7 +2019,7 @@ figure.image-display
## *与&lt;template*&gt;
When we reviewed the `NgFor`, `NgIf`, and `NgSwitch` built-in directives, we called out an oddity of the syntax: the asterisk (`*`) that appears before the directive names.
当我们审视`NgFor`、`NgIf`和`NgSwitch`内指令时,我们使用了古怪的语法:出现在指令名称前面的星号(`*`)。
当我们审视`NgFor`、`NgIf`和`NgSwitch`内指令时,我们使用了古怪的语法:出现在指令名称前面的星号(`*`)。
The `*` is a bit of syntactic sugar that makes it easier to read and write directives that modify HTML layout
with the help of templates.

View File

@ -192,7 +192,7 @@ a(id="package-json")
* `npm start` - run the compiler and a server at the same time, both in "watch mode"
* `npm start` - 同时运行编译器和一个服务器,并且都开启"监模式"
* `npm start` - 同时运行编译器和一个服务器,并且都开启"监模式"
* `npm run tsc` - run the TypeScript compiler once
@ -201,7 +201,7 @@ a(id="package-json")
* `npm run tsc:w` - run the TypeScript compiler in watch mode;
the process keeps running, awaiting changes to TypeScript files and re-compiling when it sees them.
* `npm run tsc:w` - 在监模式运行TypeScript编译器
* `npm run tsc:w` - 在监模式运行TypeScript编译器
进程持续运行并等待TypeScript文件发生变化一旦变化就重新编译它。
* `npm run lite` - run the <a href="https://www.npmjs.com/package/lite-server" target="_blank">lite-server</a>,
@ -390,7 +390,7 @@ a(id="app-component")
written in an enhanced form of HTML that tells Angular how to render this component's view.
**template**字段指定了此组件的模板。
它用一种增强的HTML式写成用来告诉Angular如何渲染此组件的视图。
它用一种增强的HTML式写成用来告诉Angular如何渲染此组件的视图。
>Our template is a single line of HTML announcing "*My First Angular App*".
@ -578,7 +578,7 @@ code-example(format="").
when working with observables.
We added the library here in QuickStart so we don't forget later.//TODO this subsection needs to be moved for when we cover the systemjs.config.js
我们的QuickStart不会用到响应式扩展但是大量的应用需要它们来提供Observable译注响应式编程的核心特性指监数据的变更以便做出响应)特性。
我们的QuickStart不会用到响应式扩展但是大量的应用需要它们来提供Observable译注响应式编程的核心特性指监数据的变更以便做出响应)特性。
我们把它加到QuickStart中以免将来忘了。//TODO 当我们覆盖到systemjs.config.js时我们得把这些内容移过去。
:marked
@ -760,7 +760,7 @@ figure.image-display
They should detect the change, recompile the TypeScript into JavaScript,
refresh the browser, and display the revised message.
TypeScript编译器和`lite-server`都在监
TypeScript编译器和`lite-server`都在监
它们会检测到文件的变化重新把这个TypeScript文件编译成JavaScript文件刷新浏览器并且显示修改过的消息。
It's a nifty way to develop an application!

View File

@ -8,14 +8,14 @@ include ../_util-fns
Our grand plan is to build an app to help a staffing agency manage its stable of heroes.
Even heroes need to find work.
我们的终极计划是构建一个程序,来帮助职业介绍所管理英雄选择器译注比如WoW登录后看到的那个列表就是“英雄选择器”)。毕竟,英雄们也得养家糊口嘛!
我们的终极计划是构建一个程序,来帮助职业介绍所管理英雄围栏译注比如WoW登录后看到的那个列表就是“英雄围栏”)。毕竟,英雄们也得养家糊口嘛!
Of course we'll only make a little progress in this tutorial. What we do build will
have many of the features we expect to find in a full-blown, data-driven application: acquiring and displaying
a list of heroes, editing a selected hero's detail, and navigating among different
views of heroic data.
当然,在这个教程中,我们只完成一小步。我们这次构建的应用将用到很多对特性:获得并显示英雄列表,编辑所选英雄的详情,并在英雄数据的多个视图之间建立导航。这些特性,在全面、数据驱动的应用中经常见到。
当然,在这个教程中,我们只完成一小步。我们这次构建的应用会涉及很多特性:获得并显示英雄列表,编辑所选英雄的详情,并在英雄数据的多个视图之间建立导航。这些特性,在成熟的、数据驱动的应用中经常见到。
The Tour of Heroes covers the core fundamentals of Angular.
Well use built-in directives to show/hide elements and display lists of hero data.
@ -28,7 +28,7 @@ include ../_util-fns
这个《英雄指南》覆盖了Angular的核心原理。
我们将使用内建指令来显示/隐藏元素,并且显示英雄数据的列表。
我们将创建一个组件来显示英雄的详情,另一个组件则用来显示英雄列表。
我们将对只读数据使用单向数据绑定。我们将添加一些可编辑字段,并使用双向数据绑定更新模型。
我们将对只读数据使用单向数据绑定。我们将添加一些可编辑字段,并通过双向数据绑定更新模型。
我们将把组件上的方法绑定到用户事件上,比如按键和点击。
我们将学习从主列表视图中选择一个英雄,然后在详情视图中编辑它。
我们将通过管道对数据进行格式化。
@ -40,8 +40,8 @@ include ../_util-fns
We'll be covering a lot of ground at an introductory level but well find plenty of links
to chapters with greater depth.
我们将学习足够的Angular核心技术以尝试起步,并建立信心 —— 证明Angular确实能做到我们需要它做的这些
我们将覆盖大部分“简介级”知识,但是我们还会放上大量链接,指向更深入的章节。
我们将学习足够的Angular核心技术来作为起步,并建立信心 —— 证明Angular确实能做到我们想让它做的
虽然我们将覆盖大部分“简介级”知识,但还会放上大量链接,指向更深入的章节。
// #enddocregion intro
@ -59,7 +59,7 @@ include ../_util-fns
Here's a visual idea of where we're going in this tour, beginning with the "Dashboard"
view and our most heroic heroes:
在这个教程中,还有一些可视化思想。放一个“仪表盘Dashboard”视图来显示我们最勇敢的英雄。
在这个教程中,还引入了一些可视化思想放一个“仪表盘Dashboard”视图来展示我们最勇敢的英雄。
figure.image-display
img(src='/resources/images/devguide/toh/heroes-dashboard-1.png' alt="英雄仪表盘的输出")
@ -69,7 +69,7 @@ figure.image-display
We could click them to navigate between this Dashboard and a Heroes view.
这个仪表盘中有两个链接:“仪表盘”和“英雄”。
我们将点击它们,以便在“仪表盘”和“英雄”视图之间导航。
我们将点击它们在“仪表盘”和“英雄”视图之间导航。
Instead we click the dashboard hero named "Magneta" and the router takes us to a "Hero Details" view
of that hero where we can change the hero's name.
@ -94,7 +94,7 @@ figure.image-display
:marked
We click a different hero and the readonly mini-detail beneath the list reflects our new choice.
当我们点击另一位英雄时,一个只读的“微型视图”会显示在列表下方,以反应我们的选择。
当我们点击另一位英雄时,一个只读的“微型视图”会显示在列表下方,以体现我们的选择。
We click the "View Details" button to drill into the
editable details of our selected hero.
@ -103,7 +103,7 @@ figure.image-display
The following diagram captures all of our navigation options.
列图标汇总了我们的所有可选导航路径。
面这个图汇总了我们所有可能的导航路径。
figure.image-display
img(src='/resources/images/devguide/toh/nav-diagram.png' alt="查看导航")
@ -111,7 +111,7 @@ figure.image-display
:marked
Here's our app in action
面是我们应用的所有动作
图演示了我们应用中的所有操作。
figure.image-display
img(src='/resources/images/devguide/toh/toh-anim.gif' alt="英雄指南的所有动作")
@ -125,12 +125,12 @@ figure.image-display
We'll motivate each step with a requirement that we've
met in countless applications. Everything has a reason.
我们将共同一步步的构建出《英雄指南》。
我们将通过与无数应用中类似的需求,驱动我们走向下一步。任何事,都会有理由。
让我们一起,一步步构建出《英雄指南》。
我们将让和无数应用类似的需求,驱动我们走向下一步。任何事,都会有理由。
And well meet many of the core fundamentals of Angular along the way.
这一路我们将遇到Angular的大量核心原则
这一路我们将遇到很多Angular核心原理
[Let's get started!](./toh-pt1.html)

View File

@ -6,7 +6,7 @@ include ../_util-fns
Every story starts somewhere. Our story starts where the [QuickStart](../quickstart.html) ends.
每个故事,都有一个起点。而我们的故事则开始于[QuickStart](../quickstart.html)的结尾处。
个故事,都有一个起点。而我们的故事则开始于[QuickStart](../quickstart.html)的结尾处。
[Run the live example for part 1](/resources/live-examples/toh-1/ts/plnkr.html)
@ -15,7 +15,7 @@ include ../_util-fns
Create a folder called `angular2-tour-of-heroes` and follow the [QuickStart](../quickstart.html) steps
which provide the prerequisites, the folder structure, and the core files for our Tour of Heroes.
创建一个名为`angular2-tour-of-heroes`的文件夹,并且遵循[QuickStart](../quickstart.html)中的步骤初始化它 —— 环境准备、目录结构,以及我们《英雄指南》的核心文件。
创建一个名为`angular2-tour-of-heroes`的文件夹,并且遵循[QuickStart](../quickstart.html)中的步骤初始化它 —— 环境准备、目录结构,并放进我们《英雄指南》的核心文件。
include ../_quickstart_repo
:marked
@ -52,7 +52,7 @@ code-example(format="" language="bash").
This command runs the compiler in watch mode, starts the server, launches the app in a browser,
and keeps the app running while we continue to build the Tour of Heroes.
这个命令会在监视模式下运行编译器,启动开发服务器,在浏览器中启动我们的应用,并在我们构建《英雄指南》的时候让应用得以持续运行。
这个命令会在监视模式下运行编译器,启动开发服务器,在浏览器中启动我们的应用,并在我们构建《英雄指南》的时候让应用得以持续运行。
.l-main-section
:marked
@ -65,7 +65,7 @@ code-example(format="" language="bash").
Let's add two properties to our `AppComponent`, a `title` property for the application name and a `hero` property
for a hero named "Windstorm".
让我们给`AppComponent`添加两个属性:`title`属性表示应用的名字,而`hero`属性表示一个名叫“Windstorm”的英雄。
我们来为`AppComponent`添加两个属性:`title`属性表示应用的名字,而`hero`属性表示一个名叫“Windstorm”的英雄。
+makeExample('toh-1/ts-snippets/app.component.snippets.pt1.ts', 'app-component-1', 'app.component.ts (AppComponent类)')(format=".")
@ -84,13 +84,13 @@ code-example(format="" language="bash").
The double curly braces tell our app to read the `title` and `hero` properties from the component and render them.
This is the "interpolation" form of one-way data binding.
这里的“双大括号”会告诉应用:从组件中读取`title`和`hero`属性,并且渲染它们。这就是单向数据绑定的“插值表达式”式。
这里的“双大括号”会告诉应用:从组件中读取`title`和`hero`属性,并且渲染它们。这就是单向数据绑定的“插值表达式”式。
.l-sub-section
:marked
Learn more about interpolation in the [Displaying Data chapter](../guide/displaying-data.html).
了解插值表达式的更多知识,参阅[“显示数据”一章](../guide/displaying-data.html)。
了解插值表达式的更多知识,参阅[“显示数据”一章](../guide/displaying-data.html)。
:marked
### Hero object
### Hero对象
@ -98,7 +98,7 @@ code-example(format="" language="bash").
At the moment, our hero is just a name. Our hero needs more properties.
Let's convert the `hero` from a literal string to a class.
此时此刻,我们的英雄还只有一个名字。显然,我们的英雄应该有更多的属性。
此时此刻,我们的英雄还只有一个名字。显然,他/她应该有更多属性。
让我们把`hero`从一个字符串字面量换成一个类。
Create a `Hero` class with `id` and `name` properties.
@ -107,36 +107,36 @@ code-example(format="" language="bash").
创建一个`Hero`类,它具有`id`和`name`属性。
现在,把下列代码放在`app.component.ts`的顶部仅次于import语句。
+makeExample('toh-1/ts/app/app.component.ts', 'hero-class-1', 'app.component.ts (Hero class)')(format=".")
+makeExample('toh-1/ts/app/app.component.ts', 'hero-class-1', 'app.component.ts (Hero)')(format=".")
:marked
Now that we have a `Hero` class, lets refactor our components `hero` property to be of type `Hero`.
Then initialize it with an id of `1` and the name, "Windstorm".
现在,有了一个`Hero`类,我们就要把组件`hero`属性的类型换成`Hero`了。
然后把`1`作为id、把“Windstorm”作为名字,初始化它。
然后以`1`为id、以“Windstorm”为名字,初始化它。
+makeExample('toh-1/ts-snippets/app.component.snippets.pt1.ts', 'hero-property-1', 'app.component.ts (Hero属性)')(format=".")
+makeExample('toh-1/ts-snippets/app.component.snippets.pt1.ts', 'hero-property-1', 'app.component.ts (hero属性)')(format=".")
:marked
Because we changed the hero from a string to an object,
we update the binding in the template to refer to the heros `name` property.
我们把hero从一个字符串换成了对象于是我们也得更新模板中的绑定表达式来引用hero的`name`属性。
我们把`hero`从一个字符串换成了对象,所以也得更新模板中的绑定表达式,来引用`hero`的`name`属性。
+makeExample('toh-1/ts-snippets/app.component.snippets.pt1.ts', 'show-hero-2')
:marked
The browser refreshes and continues to display our heros name.
浏览器自动刷新,并继续显示这位英雄的名字。
浏览器自动刷新,并继续显示这位英雄的名字。
### Adding more HTML
### 添加更多的HTML
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`.
能显示名字就算不错了,但是我们还想看到我们这位英雄的所有属性。
我们将添加一个`<div>`来显示英雄的`id`属性,另一个`<div>`来显示英雄的`name`属性。
能显示名字虽然不错,但我们还想看到这位英雄的所有属性。
我们将添加一个`<div>`来显示英雄的`id`属性,另一个`<div>`来显示英雄的`name`属性。
+makeExample('toh-1/ts-snippets/app.component.snippets.pt1.ts', 'show-hero-properties')
:marked
@ -153,13 +153,13 @@ code-example(format="" language="bash").
lets take advantage of the template strings feature
in ES2015 and TypeScript to maintain our sanity.
我们可以通过字符串加法来制作更可读的模板,但这样仍然太难看了 —— 难于阅读,容易出现
这样不行我们要借助ES2015和TypeScript提供的模板字符串来保持清
我们可以通过字符串加法来制作更可读的模板,但这样仍然太难看了 —— 难于阅读,容易拼错。
这样不行我们要借助ES2015和TypeScript提供的模板字符串来保持清
Change the quotes around the template to back-ticks and
put the `<h1>`, `<h2>` and `<div>` elements on their own lines.
把模板的双引号改成反引号,并且让`<h1>` `<h2>` `<div>`标签各占一行。
把模板的双引号改成反引号,并且让`<h1>``<h2>`和`<div>`标签各占一行。
+makeExample('toh-1/ts-snippets/app.component.snippets.pt1.ts', 'multi-line-strings', 'app.component.ts (AppComponent的 模板)')
@ -174,9 +174,9 @@ code-example(format="" language="bash").
Everything between the back-ticks at the beginning and end of the template
is part of a single template string.
**小心!**反引号(`)看起来很像单引号('),但它们是截然不同的字符。
反引号能够做的可不只是标记字符串边界。
在这里,我们只用它来把我们的模板变成多行的,而涉及更多用途。
**小心!**反引号(`虽然看起来很像单引号('),但它们是截然不同的字符。
反引号能做的可不仅仅是标记字符串的边界。
在这里,我们只用它来把我们的模板变成多行的,而没有涉及更多用途。
所有被反引号引起来的部分,都是一个单一模板字符串的一部分。
.l-main-section
@ -190,7 +190,7 @@ code-example(format="" language="bash").
Refactor the hero name `<label>` with `<label>` and `<input>` elements as shown below:
重构英雄的名字,从单纯的`<label>`到`<label>`和`<input>`元素的组合,就像下面这样:
把英雄的名字从单纯的`<label>`重构成`<label>`和`<input>`元素的组合,就像下面这样:
+makeExample('toh-1/ts-snippets/app.component.snippets.pt1.ts', 'editing-Hero', 'app.component.ts (input元素)')
:marked
@ -200,8 +200,8 @@ code-example(format="" language="bash").
is not reflected in the `<h2>`. We won't get the desired behavior
with a one-way binding to `<input>`.
在浏览器中,我们看到英雄的名字显示为了一个`<input>`文本框。但看起来还是有些不太对
当修改名字时,我们的改动并没有反映到`<h2>`中。使用单向数据绑定,我们没法实现所期望的行为。
在浏览器中,我们看到英雄的名字显示成一个`<input>`文本框。但看起来还是有点儿不太对劲
当修改名字时,我们的改动并没有反映到`<h2>`中。使用单向数据绑定,我们没法实现所期望的这种行为。
### Two-Way Binding
### 双向绑定
@ -211,11 +211,11 @@ code-example(format="" language="bash").
In short, we want two-way data binding.
我们的期望是:在`<input>`中显示英雄的名字,修改它,并且在所有绑定到英雄名字的地方看到这些修改。
长话短说:我们需要双向数据绑定。
简而言之,我们需要双向数据绑定。
Lets update the template to use the **`ngModel`** built-in directive for two-way binding.
让我们通过**`ngModel`**内指令提供的双向数据绑定机制来更新模板。
让我们通过**`ngModel`**内指令提供的双向数据绑定机制来更新模板。
.l-sub-section
:marked
@ -223,7 +223,7 @@ code-example(format="" language="bash").
[Forms](../guide/forms.html#ngModel) and
[Template Syntax](../guide/template-syntax.html#ngModel) chapters.
学习`ngModel`的更多知识,参见[表单](../guide/forms.html#ngModel)和
学习关于`ngModel`的更多知识,参见[表单](../guide/forms.html#ngModel)和
[模板语法](../guide/template-syntax.html#ngModel)两章
:marked
Replace the `<input>` with the following HTML
@ -237,7 +237,7 @@ code-example(language="html").
The browser refreshes. We see our hero again. We can edit the heros name and
see the changes reflected immediately in the `<h2>`.
浏览器刷新。再次见到我们的英雄。我们可以编辑英雄的名字,并且看到改动立刻体现在`<h2>`中。
浏览器刷新。又见到我们的英雄了。我们可以编辑英雄的名字,也能看到这个改动立刻体现在`<h2>`中。
.l-main-section
:marked
@ -245,7 +245,7 @@ code-example(language="html").
## 我们已经走过的路
Lets take stock of what weve built.
我们来清点一下已经构建完成的
我们来盘点一下已经构建完成的部分
* Our Tour of Heroes uses the double curly braces of interpolation (a form of one-way data binding)
to display the application title and properties of a `Hero` object.
@ -254,9 +254,9 @@ code-example(language="html").
* 我们使用ES2105的模板字符串写了一个多行模板来让我们的模板更有可读性。
* We can both display and change the heros name after adding a two-way data binding to the `<input>` element
using the built-in `ngModel` directive.
* 为了同时显示和修改英雄的名字,我们还使用了内建的`ngModel`指令,往`<input>`元素上添加双向数据绑定。
* 为了同时显示和修改英雄的名字,我们还使用了内建的`ngModel`指令,往`<input>`元素上添加双向数据绑定。
* The `ngModel` directive also propagates changes to every other binding of the `hero.name`.
* 通过`ngModel`指令,这些修改还影响到`hero.name`的每一个其它绑定。
* 通过`ngModel`指令,这些修改还影响到了每一个对`hero.name`的其它绑定。
[Run the live example for part 1](/resources/live-examples/toh-1/ts/plnkr.html)
@ -278,7 +278,7 @@ code-example(language="html").
template, and allow a user to select it in the
[next tutorial chapter](./toh-pt2.html).
我们的《英雄指南》只显示了一个英雄,而我们真正显示的是一个英雄列表。
我们还希望允许用户选择一个英雄,并且显示他的详情。
我们的《英雄指南》只显示了一个英雄,而我们真正显示的是一个英雄列表。
我们还希望允许用户选择一个英雄,并且显示他/她的详情。
我们还将学习更多:接收一个列表、把它们绑定到模板,以及让用户选择它。
这些都在[教程的下一章](./toh-pt2.html)。

View File

@ -2,12 +2,12 @@ include ../_util-fns
:marked
# It Takes Many Heroes
# 带来多个英雄
# 需要多个英雄
Our story needs more 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.
我们的故事需要更多的英雄。我们将扩展我们的《英雄指南》,来显示一个英雄列表,运行用户选择一个英雄,并且显示英雄的详情。
我们的故事需要更多的英雄了。我们将扩展这个《英雄指南》,来显示一个英雄列表,允许用户选择一个英雄,并且显示英雄的详情。
[Run the live example for part 2](/resources/live-examples/toh-2/ts/plnkr.html)
@ -17,8 +17,8 @@ include ../_util-fns
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.
我们来清点一下显示英雄列表都需要点什么。
首先,我们需要一英雄列表数据。我们还要把这些英雄显示到一个视图的模板中,所以,我们需要用某种途径来做到这一点。
我们来盘点一下显示英雄列表都需要些什么。
首先,我们需要一英雄列表数据。我们还要把这些英雄显示到一个视图的模板中,所以,我们需要用某种途径来做到这一点。
.l-main-section
:marked
@ -28,7 +28,7 @@ include ../_util-fns
lets verify we have the following structure after [Part 1](./toh-pt1.html).
If not, well need to go back to Part 1 and figure out what we missed.
在继续《英雄指南》的第二部分之前,我们先检查一下,完成[第一部分](./toh-pt1.html)之后,你是否已经有了如下目录结构。如果没有,你得先回到第一部分,看看了哪里。
在继续《英雄指南》的第二部分之前,我们先检查一下,完成[第一部分](./toh-pt1.html)之后,你是否已经有了如下目录结构。如果没有,你得先回到第一部分,看看错过了哪里。
.filetree
.file angular2-tour-of-heroes
@ -78,21 +78,21 @@ code-example(format="." language="bash").
We aspire to fetch this list of heroes from a web service, but lets take small steps
first and display mock heroes.
`HEROS`变量是一个由`Hero`类的实例构成的数组,我们在第一部分定义过它。
我们当然希望从一个Web服务中获取这个英雄列表是,别急,我们得把步子迈得小一点 —— 先用一组Mock模拟对象)出来的英雄。
`HEROES`变量是一个由`Hero`类的实例构成的数组,我们在第一部分定义过它。
我们当然希望从一个Web服务中获取这个英雄列表但别急我们得把步子迈得小一点 —— 先用一组Mock模拟出来的英雄。
### Exposing heroes
### 导出英雄们
Lets create a 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 (英雄数组属性)')
:marked
We did not have to define the `heroes` type. TypeScript can infer it from the `HEROES` array.
我们并不需要明确定义`heroes`属性的类型TypeScript能从`HEROES`数组中推断出来。
我们并不需要明确定义`heroes`属性的数据类型TypeScript能从`HEROES`数组中推断出来。
.l-sub-section
:marked
We could have defined the heroes list here in this component class.
@ -101,15 +101,15 @@ code-example(format="." language="bash").
from the class implementation from the start.
我们已经把英雄列表定义在了这个组件类中。
是显然,我们最后还是得从一个数据服务中获取这些英雄。
正因如此,我们从一开始就有意识的把英雄数据隔离到一个类中来实现。
显然,我们最终还是得从一个数据服务中获取这些英雄。
正因如此,我们从一开始就有意识的把英雄数据隔离到一个类中来实现。
:marked
### Displaying heroes in a template
### 在一个模板中显示英雄
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.
我们的组件有`heroes`属性,我们来到模板中创建一个无序列表来显示他们。
我们的组件有了`heroes`属性,我们再到模板中创建一个无序列表来显示他们。
我们将在标题和英雄详情之间插入下面这段HTML代码。
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'heroes-template-1', 'app.component.ts (英雄模板)')
@ -117,7 +117,7 @@ code-example(format="." language="bash").
:marked
Now we have a template that we can fill with our heroes.
现在,我们有了一个模板,接下来,我们用英雄们的数据来填充它。
现在,我们有了一个模板。接下来,就用英雄们的数据来填充它。
### Listing heroes with ngFor
### 通过ngFor来显示英雄列表
@ -126,12 +126,12 @@ code-example(format="." language="bash").
and display them individually.
Well need some help from Angular to do this. Lets do this step by step.
我们想要把组件中的`heroes`数组绑定到模板中,迭代并逐个显示他们。
这下我们就得借助Angular的帮助来完成它了。让我们一步步的实现它!
我们想要把组件中的`heroes`数组绑定到模板中,迭代并逐个显示他们。
这下我们就得借助Angular的帮助来完成它了。我们来一步步儿实现它!
First modify the `<li>` tag by adding the built-in directive `*ngFor`.
首先,修改`<li>`标,往上添加内建指令:`*ngFor`。
首先,修改`<li>`标,往上添加内建指令:`*ngFor`。
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'heroes-ngfor-1', 'app.component.ts (ngFor)')
@ -151,32 +151,32 @@ code-example(format="." language="bash").
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`数组上迭代,并输出此模板的实例。
`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`变量,并让它在其对应的模板实例中可用*”
引号中赋值给`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 heros 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)章
学习更多关于`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 heros properties.
现在,我们在`<li>`标中插入一些内容,以便使用模板变量`hero`来显示英雄的属性。
现在,我们在`<li>`标中插入一些内容,以便使用模板变量`hero`来显示英雄的属性。
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'ng-for', 'app.component.ts (ngFor模板)')(format=".")
@ -191,7 +191,7 @@ code-example(format="." language="bash").
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
to the following CSS classes:
@ -208,8 +208,8 @@ code-example(format="." language="bash").
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中。
当我们把样式赋予一个组件时,它们的作用范围将仅限于组件。
即:此样式只会作用于这个`AppComponent`组件,而不会泄露到外部HTML中。
Our template for displaying the heroes should now look like this:
@ -221,8 +221,8 @@ code-example(format="." 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.
We'll do this in a later chapter. For now let's keep rolling.
样式有很多种写法!我们可以像这里一样内联在代码中,或者我们可以把它们移出去,放到各自的文件中,以便为组件编码时更容易。
到后面的章节中我们就会这么干,但现在,我们还是保持现在的节奏
样式有很多种写法!我们可以像这里一样内联在代码中,也可以把它们移出去,放到各自的文件中,以便给组件编码时更容易。
等到后面的章节中我们肯定会这么干,但现在,还是保持现在的节奏吧
.l-main-section
:marked
@ -242,13 +242,13 @@ code-example(format="." language="bash").
Lets connect the master to the detail through a `selectedHero` component property bound to a click event.
我们通过组件中一个`selectedHero`属性来连接主从视图。它被绑定到了一个click事件上。
我们通过组件中一个`selectedHero`属性来连接主从视图。它被绑定到了click事件上。
### Click event
### click事件
We modify the `<li>` by inserting an Angular event binding to its click event.
我们往`<li>`元素上插入一个Angular事件绑定代码来绑定到click事件上
我们往`<li>`元素上插入一句Angular事件绑定代码绑定到它的click事件
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'selectedHero-click', 'app.component.ts (捕获click事件)')
@ -264,8 +264,8 @@ code-example(format="." language="bash").
passing the template input variable `hero` as an argument.
Thats the same `hero` variable we defined previously in the `ngFor`.
圆括号表示`<li>`元素上的`click`事件是我们要绑定的目标。
等号右边的表达式调用`AppComponent`的`onSelect()`方法,并把局部模板变量`hero`作为参数传进去。
圆括号表示`<li>`元素上的`click`事件是我们要绑定的目标。
等号右边的表达式调用`AppComponent`的`onSelect()`方法,并把模板输入变量`hero`作为参数传进去。
它和我们前面在`ngFor`中定义的`hero`变量是同一个。
.l-sub-section
@ -274,9 +274,9 @@ code-example(format="." language="bash").
[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)章
[模板语法](../guide/template-syntax.html#event-binding)章。
:marked
### Add the click handler
@ -289,11 +289,11 @@ code-example(format="." language="bash").
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.
我们的组件还没有用来表示“当前选中的英雄”的变量,我们就从这一步开始。
我们的组件还没有用来表示“当前选中的英雄”的变量,我们就从这一步开始。
### Expose the selected hero
### 导出“当前选中的英雄”
@ -302,7 +302,7 @@ code-example(format="." language="bash").
**Replace** it with this simple `selectedHero` property:
在`AppComponent`上,我们不再需要一个固定的`hero`属性。
把它替换为`selectedHero`属性。
那就直接把它改为`selectedHero`属性。
+makeExample('toh-2/ts/app/app.component.ts', 'selected-hero-1', 'app.component.ts (selectedHero)')
@ -310,11 +310,11 @@ code-example(format="." language="bash").
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`.
我们决定:在用户选取之前,我们不会默认选择任何英雄,所以,我们不会去像`hero`一样初始化`selectedHero`变量。
我们决定:在用户选取之前,不会默认选择任何英雄,所以,我们不用像`hero`一样去初始化`selectedHero`变量。
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-1', 'app.component.ts (onSelect)')
:marked
@ -323,18 +323,18 @@ code-example(format="." language="bash").
Lets fix the template to bind to the new `selectedHero` property.
我们将把所选英雄的详细信息显示在模板中。目前,它仍然引用的是以前的`hero`属性。
我们这就修改模板,让它绑定到新的`selectedHero`属性上。
我们这就修改模板,让它绑定到新的`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隐藏空的详情
### 利用ngIf隐藏空的详情
When our app loads we see a list of heroes, but a hero is not selected.
The `selectedHero` is `undefined`.
Thats why we'll see the following error in the browsers console:
当应用刚加载时,我们会看到一个英雄列表,但还没有任何英雄被选中。
当应用刚加载时,我们会看到一个英雄列表,但还没有任何英雄被选中。
`selectedHero`属性是`undefined`。
因此,我们会看到浏览器控制台中出现下列错误:
code-example(language="html").
@ -345,7 +345,7 @@ code-example(format="." language="bash").
This name property does not exist because `selectedHero` itself is undefined.
记住,我们要在模板中显示的是`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.
@ -354,7 +354,7 @@ code-example(format="." language="bash").
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`内置指令添加上去,然后把它的值设置为本组件的`selectedHero`属性。
我们把模板中的“英雄详情”内容区用div包裹起来。然后往上添加一个`ngIf`内建指令,然后把`ngIf`的值设置为本组件的`selectedHero`属性。
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'ng-if', 'app.component.ts (ngIf)')
@ -478,7 +478,7 @@ code-example(format="." language="bash").
* 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
* 我们学会了如何在组件模板中使用内的`ngIf`和`ngFor`指令
* 我们学会了如何在组件模板中使用内的`ngIf`和`ngFor`指令
[Run the live example for part 2](/resources/live-examples/toh-2/ts/plnkr.html)
@ -494,4 +494,4 @@ code-example(format="." language="bash").
我们的《英雄指南》长大了,但还远远不够完善。
我们显然不能把整个应用都放进一个组件中。
我们需要把它拆分成一系列子组件,然后教它们协同工作 ——
就像我们[下一章](toh-pt3.html)学到的一样。
就像我们将在[下一章](toh-pt3.html)学到的那样。

View File

@ -5,7 +5,7 @@ include ../_util-fns
Use cases are flowing in for reusing components, passing data to components, and creating more reusable assets. Let's separate the heroes list from the hero details and make the details component reusable.
我们的应用继续成长。
这次的例子将依次展示:复用组件、给组件传入数据、创建高复用度的软件资产。我们先把英雄列表从英雄详情中分离出来,并且让详情组件可复用。
这次的例子将依次展示:复用组件、给组件传入数据以及创建更容易复用的软件资产。我们先把英雄列表从英雄详情中分离出来,并且让详情组件可复用。
[Run the live example for part 3](/resources/live-examples/toh-3/ts/plnkr.html)
@ -17,7 +17,7 @@ include ../_util-fns
## 我们在哪儿
Before we continue with our Tour of Heroes, lets verify we have the following structure. If not, well need to go back and follow the previous chapters.
在继续《英雄指南》之前,我们先检查一下,你是否已经有了如下目录结构。如果没有,你得先回上一章,看看了哪里。
在继续《英雄指南》之前,我们先检查一下,你是否已经有了如下目录结构。如果没有,你得先回上一章,看看错过了哪里。
.filetree
.file angular2-tour-of-heroes
@ -39,7 +39,7 @@ include ../_util-fns
### 让应用代码保持转译和运行
We want to start the TypeScript compiler, have it watch for changes, and start our server. We'll do this by typing
我们要启动TypeScript编译器它会监视文件变更并启动开发服务器。我们只要敲:
我们要启动TypeScript编译器它会监视文件变更并启动开发服务器。只要敲
code-example(format="." language="bash").
npm start
@ -61,8 +61,8 @@ code-example(format="." language="bash").
我们的英雄列表和英雄详情目前位于同一个文件的同一个组件中。
现在它们还很小,但很快它们都会长大。
我们将来肯定会收到新需求:针对这一个,却不能影响另一个。
然而,每一个更改都会给这两个组件带来风险,并且带来双倍的测试负担,却不会带来好处。
如果我们不得不在应用之外复用英雄详情组件,那么英雄列表组件也会跟着混进去。
然而,每一个更改都会给这两个组件带来风险,并且带来双倍的测试负担,却没有任何好处。
如果我们不得不在应用之外复用英雄详情组件,那么英雄列表组件也会跟着混进去。
Our current component violates the
[Single Responsibility Principle](https://blog.8thlight.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html).
@ -70,7 +70,7 @@ code-example(format="." language="bash").
especially if doing them right is easy and we learn how to build Angular apps in the process.
我们这个组件违反了[单一职责原则](https://blog.8thlight.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html)。
虽然这只是一个教程,但我们还是要坚持做正确的事 —— 况且,做正确的事如此容易我们何乐而不为呢别忘了我们正在学习的就是如何构建真正的Angular应用。
虽然这只是一个教程,但我们还是得坚持做正确的事 —— 况且,做正确的事这么容易我们何乐而不为呢别忘了我们正在学习的就是如何构建真正的Angular应用。
Lets break the hero details out into its own component.
@ -79,6 +79,7 @@ code-example(format="." language="bash").
### Separating the Hero Detail Component
### 拆分英雄详情组件
Add a new file named `hero-detail.component.ts` to the `app` folder and create `HeroDetailComponent` as follows.
在`app`目录下添加一个名叫`hero-detail.component.ts`的文件,并且创建`HeroDetailComponent`。代码如下:
+makeExample('toh-3/ts/app/hero-detail.component.ts', 'v1', 'hero-detail.component.ts (初始版本)')(format=".")
@ -93,7 +94,7 @@ code-example(format="." language="bash").
Notice that we have an `AppComponent` in a file named `app.component.ts` and our new
`HeroDetailComponent` is in a file named `hero-detail.component.ts`.
注意,在名叫`app.component.ts`的文件中有一个`AppComponent`组件,在名叫`hero-detail.component.ts`的文件中有一个`HeroDetailComponent`组件。
你会注意,在名叫`app.component.ts`的文件中有一个`AppComponent`组件,在名叫`hero-detail.component.ts`的文件中有一个`HeroDetailComponent`组件。
All of our component names end in "Component". All of our component file names end in ".component".
@ -102,7 +103,7 @@ code-example(format="." language="bash").
We spell our file names in lower dash case (AKA "kebab-case") so we don't worry about
case sensitivity on the server or in source control.
这里我们使用小写中线命名法(也叫烤串命名法),所以我们不用担心它在服务器或者版本控制系统中出现大小写问题。
这里我们使用小写中线命名法(也叫烤串命名法)拼写文件名,所以不用担心它在服务器或者版本控制系统中出现大小写问题。
<!-- TODO
.l-sub-section
:marked
@ -114,26 +115,26 @@ code-example(format="." language="bash").
:marked
We begin by importing the `Component` and `Input` decorators from Angular because we're going to need them soon.
一开始我们先从Angular中导入`Component`和`Input`装饰器,因为马上就会用到它们。
一开始,我们先从Angular中导入`Component`和`Input`装饰器,因为马上就会用到它们。
We create metadata with the `@Component` decorator where we
specify the selector name that identifies this component's element.
Then we export the class to make it available to other components.
我们使用`@Component`装饰器创建元数据在元数据中,我们指定选择器的名字,用以标记此组件的元素。
然后,我们导出这个类,以便其它组件可以使用它。
我们使用`@Component`装饰器创建元数据在元数据中,我们指定选择器的名字,用以标记此组件的元素。
然后,我们导出这个组件类,以便其它组件可以使用它。
When we finish here, we'll import it into `AppComponent` and create a corresponding `<my-hero-detail>` element.
做完这些,我们把它导入`AppComponent`组件,并创建相应的`<my-hero-detail>`元素。
做完这些,我们把它导入`AppComponent`组件,并创建相应的`<my-hero-detail>`元素。
:marked
#### Hero Detail Template
#### 英雄详情模板
At the moment, the *Heroes* and *Hero Detail* views are combined in one template in `AppComponent`.
Lets **cut** the *Hero Detail* content from `AppComponent` and **paste** it into the new template property of `HeroDetailComponent`.
目前,在`AppComponent`中 *英雄列表* 和 *英雄详情* 视图被组合在同一个模板中。
我们从`AppComponent`中 **剪切** *英雄详情* 的内容,并且粘贴到`HeroDetailComponent`组件的`template`属性中。
目前,`AppComponent`的*英雄列表*和*英雄详情*视图被组合在同一个模板中。
我们从`AppComponent`中**剪切**出*英雄详情*的内容,并且粘贴到`HeroDetailComponent`组件的`template`属性中。
We previously bound to the `selectedHero.name` property of the `AppComponent`.
Our `HeroDetailComponent` will have a `hero` property, not a `selectedHero` property.
@ -141,15 +142,15 @@ code-example(format="." language="bash").
The result looks like this:
以前我们绑定到了`AppComponent`的`selectedHero.name`属性中。
我们的`HeroDetailComponent`组件将会有一个`hero`属性,而不是`selectedHero`属性。
所以,我们把模板中的所有`selectedHero`替换为`hero`。只改这些就够了。
`HeroDetailComponent`组件将会有一个`hero`属性,而不是`selectedHero`属性。
所以,我们把模板中的所有`selectedHero`替换为`hero`。只改这些就够了。
最终结果如下所示:
+makeExample('toh-3/ts/app/hero-detail.component.ts', 'template', 'hero-detail.component.ts (模板)')(format=".")
:marked
Now our hero detail layout exists only in the `HeroDetailComponent`.
现在,我们的英雄详情布局只存在于`HeroDetailComponent`组件中。
现在,我们的英雄详情布局只存在于`HeroDetailComponent`组件中
#### Add the *hero* property
#### 添加 *hero* 属性
@ -166,7 +167,7 @@ code-example(format="." language="bash").
We solve the problem by relocating the `Hero` class from `app.component.ts` to its own `hero.ts` file.
解决这个问题,我们也从`app.component.ts`文件中把`Hero`类移到属于它自己的`hero.ts`文件中。
要解决这个问题,我们也从`app.component.ts`文件中把`Hero`类移到属于它自己的`hero.ts`文件中。
+makeExample('toh-3/ts/app/hero.ts', null, 'hero.ts (导出Hero类)')(format=".")
@ -174,54 +175,54 @@ code-example(format="." language="bash").
We export the `Hero` class from `hero.ts` because we'll need to reference it in both component files.
Add the following import statement near the top of both `app.component.ts` and `hero-detail.component.ts`.
我们从`hero.ts`中导出`Hero`类,这是因为我们需要从这些组件文件中引用它。
我们得从`hero.ts`中导出`Hero`类,因为我们要从那些组件文件中引用它。
在`app.component.ts`和`hero-detail.component.ts`的顶部添加下列import语句
+makeExample('toh-3/ts/app/hero-detail.component.ts', 'hero-import', 'hero-detail.component.ts与app.component.ts(导入Hero类)')
:marked
#### The *hero* property is an ***input***
#### *hero* 是一个 ***输入*** 属性
#### *hero*是一个***输入***属性
The `HeroDetailComponent` must be told what hero to display. Who will tell it? The parent `AppComponent`!
还得告诉`HeroDetailComponent`显示哪个英雄。谁告诉它呢?自然是父组件`AppComponent`
还得告诉`HeroDetailComponent`显示哪个英雄。谁告诉它呢?自然是父组件`AppComponent`
The `AppComponent` knows which hero to show: the hero that the user selected from the list.
The user's selection is in its `selectedHero` property.
`AppComponent`自然知道该显示哪个英雄:用户从列表中选中的那个。
这个英雄就是`selectedHero`属性的值。
`AppComponent`确实知道该显示哪个英雄 —— 用户从列表中选中的那个。
这个英雄就是`selectedHero`属性的值。
We will soon update the `AppComponent` template so that it binds its `selectedHero` property
to the `hero` property of our `HeroDetailComponent`. The binding *might* look like this:
我们马上就要升级`AppComponent`模板,以便把该组件的`selectedHero`属性绑定到`HeroDetailComponent`组件的`hero`属性上。
绑定看起来可能是这样的:
我们马上升级`AppComponent`模板,以便把该组件的`selectedHero`属性绑定到`HeroDetailComponent`组件的`hero`属性上。
绑定看起来*可能*是这样的:
code-example(format=".").
&lt;my-hero-detail [hero]="selectedHero">&lt;/my-hero-detail>
:marked
Notice that the `hero` property is the ***target*** of a property binding &mdash; it's in square brackets to the left of the (=).
注意,在等号(=)左边方括号中的这个`hero`是属性绑定的目标。
注意,在等号(=)左边方括号中的这个`hero`是属性绑定的***目标***
Angular insists that we declare a ***target*** property to be an ***input*** property.
If we don't, Angular rejects the binding and throws an error.
Angular期望我们把 ***目标属性*** 定义成组件的 ***输入属性*** 否则Angular会拒绝绑定并且抛出一个错误。
Angular希望我们把***目标属性***定义成组件的***输入属性***否则Angular会拒绝绑定并且抛出一个错误。
.l-sub-section
:marked
We explain input properties in more detail [here](../guide/attribute-directives.html#why-input)
where we also explain why *target* properties require this special treatment and
*source* properties do not.
我们在[这里](../guide/attribute-directives.html#why-input)详细解释了输入属性,以及为什么 *目标属性* 需要这种特殊待遇,而 *来源属性* 却不需要。
我们在[这里](../guide/attribute-directives.html#why-input)详细解释了输入属性,以及为什么*目标属性*需要“显式定义”这样的特殊待遇,而*来源属性*却不需要。
:marked
There are a couple of ways we can declare that `hero` is an *input*.
We'll do it the way we *prefer*, by annotating the `hero` property with the `@Input` decorator that we imported earlier.
我们有一大堆方式把`hero`声明成 *输入属性*
这里我们采用建议的方式:使用我们前面导入的`@Input`装饰器,为`hero`属性加上注解。
我们有几种方式把`hero`声明成*输入属性*
这里我们采用*首选*的方式:使用我们前面导入的`@Input`装饰器,为`hero`属性加上注解。
+makeExample('toh-3/ts/app/hero-detail.component.ts', 'hero-input')(format='.')
.l-sub-section
@ -247,7 +248,7 @@ code-example(format=".").
Find the location in the template where we removed the *Hero Detail* content
and add an element tag that represents the `HeroDetailComponent`.
找到我们刚刚从模板中移除 *英雄详情* 的地方,放上用来表示`HeroDetailComponent`组件的HTML标
找到我们刚刚从模板中移除*英雄详情*的地方,放上用来表示`HeroDetailComponent`组件的HTML标
code-example(format=".").
&lt;my-hero-detail>&lt;/my-hero-detail>
.l-sub-section
@ -260,7 +261,7 @@ code-example(format=".").
to the `HeroDetailComponent` element's `hero` property like this:
这两个组件目前还不能协同工作,直到我们把`AppComponent`组件的`selectedHero`属性和`HeroDetailComponent`组件的`hero`属性绑定在一起,就像这样:
code-example(format=".")
code-example(format=".").
&lt;my-hero-detail [hero]="selectedHero">&lt;/my-hero-detail>
:marked
The `AppComponent`s template should now look like this
@ -272,12 +273,12 @@ code-example(format=".")
Thanks to the binding, the `HeroDetailComponent` should receive the hero from the `AppComponent` and display that hero's detail beneath the list.
The detail should update every time the user picks a new hero.
感谢数据绑定机制,`HeroDetailComponent`组件可以从`AppComponent`组件中获取英雄数据,并且在列表的下方显示英雄的详情。
感谢数据绑定机制,`HeroDetailComponent`组件应该能从`AppComponent`组件中获取英雄数据,并且在列表的下方显示英雄的详情
每当用户选中一个新的英雄时,详情信息应该随之更新。
It's not happening yet!
但什么没有发生!
但什么没有发生!
We click among the heroes. No details. We look for an error in the console of the browser development tools. No error.
@ -285,22 +286,22 @@ code-example(format=".")
It is as if Angular were ignoring the new tag. That's because *it is ignoring the new tag*.
看起来像是Angular忽略了这个新标记。确实这是因为 *它忽略了不认识的标记*
看起来好像Angular忽略了这个新标签。确实如此这是因为*它忽略了不认识的标签*
### The *directives* array
### *directives* 数组
A browser ignores HTML tags and attributes that it doesn't recognize. So does Angular.
浏览器会忽略它不认识的HTML标记和属性。Angular也是这样
浏览器会忽略它不认识的HTML标签和属性。Angular也是如此
We've imported `HeroDetailComponent`, we've used it in the template, but we haven't told Angular about it.
我们引入了`HeroDetailComponent`并在模板中使用它但Angular还不知道它
我们引入了`HeroDetailComponent`,并在模板中使用它,但还没有告诉Angular。
We tell Angular about it by listing it in the metadata `directives` array. Let's add that array property to the bottom of the
`@Component` configuration object, immediately after the `template` and `styles` properties.
我们把它列在元数据的`directies`数组中这样Angular才会知道它。
我们把这个数组属性加在`@Component`配置对象的底部,`template`和`styles`属性中间
我们把它列在元数据的`directives`数组中这样Angular才会知道它。
我们把这个数组属性加在`@Component`配置对象的底部,紧跟在`template`和`styles`属性之后
+makeExample('toh-3/ts/app/app.component.ts', 'directives')
@ -312,12 +313,12 @@ code-example(format=".")
When we select a hero we can see the selected heros details.
当在浏览器中查看应用时,我们看到了英雄列表。
当选中一个英雄时,我们还能看到所选英雄的详情。
当选中一个英雄时,还能看到所选英雄的详情。
What's fundamentally new is that we can use this `HeroDetailComponent`
to show hero details anywhere in the app.
我们所关注的进步是:我们可以在应用中的任何地方使用这个`HeroDetailComponent`组件来显示英雄详情了。
值得关注的进步是:我们可以在应用中的任何地方使用这个`HeroDetailComponent`组件来显示英雄详情了。
Weve created our first reusable component!
@ -327,7 +328,7 @@ code-example(format=".")
### 回顾应用结构
Lets verify that we have the following structure after all of our good refactoring in this chapter:
来验证下吧,在本章中,经过这些漂亮的重构,我们应该得到下列结构:
来验证下吧,在本章中,经过这些漂亮的重构,我们应该得到下列结构:
.filetree
.file angular2-tour-of-heroes
@ -347,7 +348,7 @@ code-example(format=".")
:marked
Here are the code files we discussed in this chapter.
这就是我们在本章讨论过的这些源码文件:
下面就是我们在本章讨论过的源码文件:
+makeTabs(`
toh-3/ts/app/hero-detail.component.ts,
@ -386,17 +387,17 @@ code-example(format=".")
## 前方的路
Our Tour of Heroes has become more reusable with shared components.
通过抽取共享组件,我们的《英雄指南》变得更加可复用了。
通过抽取共享组件,我们的《英雄指南》变得更有复用性了。
We're still getting our (mock) data within the `AppComponent`.
That's not sustainable.
We should refactor data access to a separate service
and share it among the components that need data.
在`AppComponent`中我们仍然使用着mock数据。
这种方式可没法“可持续发展”。
在`AppComponent`中我们仍然使用着mock数据。
显然,这种方式不能“可持续发展”。
我们要把数据访问逻辑抽取到一个独立的服务中,并在需要数据的组件之间共享。
Well learn to create services in the [next tutorial](toh-pt4.html) chapter.
在[下一步](toh-pt4.html),我们将学习如何创建服务。
在[下一步](toh-pt4.html),我们将学习如何创建服务。

View File

@ -37,7 +37,7 @@ include ../_util-fns
Before we continue with our Tour of Heroes, lets verify we have the following structure.
If not, well need to go back and follow the previous chapters.
在继续《英雄指南》之前,我们先检查一下,你是否已经有了如下目录结构。如果没有,你得先回上一章,看看了哪里。
在继续《英雄指南》之前,我们先检查一下,你是否已经有了如下目录结构。如果没有,你得先回上一章,看看错过了哪里。
.filetree
.file angular2-tour-of-heroes
@ -111,7 +111,7 @@ code-example(format="." language="bash").
The `SpecialSuperHeroService` would be defined in the `special-super-hero.service.ts` file.
我们遵循的文件命名约定是:服务名称的小写形式(基本名),加上`.service`后缀。
如果服务名称包含多个字母,我们把基本名部分拼成中线格式dash-case也被称作烤串格式kebab-case
如果服务名称包含多个字母,我们把基本名部分拼成中线形式dash-case也被称作烤串形式kebab-case
于是,`SpecialSuperHeroService`服务应该被定义在`special-super-hero.service.ts`文件中。
:marked
We name the class `HeroService` and export it for others to import.
@ -345,7 +345,7 @@ code-example(format="." language="html").
Recall that the `AppComponent` creates an instance of `HeroDetail` by virtue of the
`<my-hero-detail>` tag at the bottom of its template. That `HeroDetail` is a child of the `AppComponent`.
回忆一下,`AppComponent`在它的模板底部包含了一个`<my-hero-detail>`标,于是创建了一个`HeroDetail`的实例。这个`HeroDetail`就叫做`AppComponent`的子组件。
回忆一下,`AppComponent`在它的模板底部包含了一个`<my-hero-detail>`标,于是创建了一个`HeroDetail`的实例。这个`HeroDetail`就叫做`AppComponent`的子组件。
If the `HeroDetailComponent` needed its parent component's `HeroService`,
it would ask Angular to inject the service into its constructor which would look just like the one for `AppComponent`:

View File

@ -71,11 +71,11 @@ div
h3 Animation
h3 动画
p(class="text-body") Create high performance complex choreographies and animation timelines with very little code through Angular's intuitive API.
p(class="text-body") 通过Angular中直观的API创建高性能复杂编排和动画时间线 —— 只要非常少的代码。
p(class="text-body") 通过Angular中直观简便的API创建高性能复杂编排和动画时间线 —— 只要非常少的代码。
div(class="feature")
h3 Accessibility
h3 可访问性
p(class="text-body") Create accessible applications with ARIA-enabled components, developer guides, and built-in a11y test infrastructure.
p(class="text-body") 通过支持ARIA的组件、开发者指南和内的一体化测试基础设施,创建具有完备可访问性的应用。
p(class="text-body") 通过支持ARIA的组件、开发者指南和内的一体化测试基础设施,创建具有完备可访问性的应用。
!= partial("/_includes/_cta-bar")