Merge branch 'master' of https://github.com/angular-live/angular.io
This commit is contained in:
commit
55722de87a
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -948,7 +948,7 @@ figure.image-display
|
||||
control* is valid.
|
||||
|
||||
`NgForm`指令使用额外的特性扩充了`form`元素。
|
||||
它保存我们通过`ngControl`属性为各个元素创建的控件类,并且监听它们的属性变化,包括有效性。
|
||||
它保存我们通过`ngControl`属性为各个元素创建的控件类,并且监视它们的属性变化,包括有效性。
|
||||
它还有自己的`valid`属性,只有当 *每一个被包含的控件* 都有效时,它才有效。
|
||||
|
||||
:marked
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
## *与<template*>
|
||||
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.
|
||||
|
@ -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!
|
||||
|
@ -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.
|
||||
We’ll 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 we’ll 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 we’ll meet many of the core fundamentals of Angular along the way.
|
||||
|
||||
这一路,我们将遇到Angular的大量核心原则。
|
||||
这一路上,我们将遇到很多Angular核心原理。
|
||||
|
||||
[Let's get started!](./toh-pt1.html)
|
||||
|
||||
|
@ -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, let’s refactor our component’s `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 hero’s `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 hero’s name.
|
||||
|
||||
浏览器自动刷新,并且继续显示这位英雄的名字。
|
||||
浏览器自动刷新,并继续显示这位英雄的名字。
|
||||
|
||||
### Adding more HTML
|
||||
### 添加更多的HTML
|
||||
Displaying a name is good, but we want to see all of our hero’s properties.
|
||||
We’ll add a `<div>` for our hero’s `id` property and another `<div>` for our hero’s `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").
|
||||
let’s 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>`中显示英雄的名字,修改它,并且在所有绑定到英雄名字的地方看到这些修改。
|
||||
长话短说:我们需要双向数据绑定。
|
||||
简而言之,我们需要双向数据绑定。
|
||||
|
||||
Let’s 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 hero’s name and
|
||||
see the changes reflected immediately in the `<h2>`.
|
||||
|
||||
浏览器刷新。再次见到我们的英雄。我们可以编辑英雄的名字,并且看到改动立刻体现在`<h2>`中。
|
||||
浏览器刷新。又见到我们的英雄了。我们可以编辑英雄的名字,也能看到这个改动立刻体现在`<h2>`中。
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
@ -245,7 +245,7 @@ code-example(language="html").
|
||||
## 我们已经走过的路
|
||||
Let’s take stock of what we’ve 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 hero’s 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)。
|
||||
|
@ -2,12 +2,12 @@ include ../_util-fns
|
||||
|
||||
:marked
|
||||
# It Takes Many Heroes
|
||||
# 带来多个英雄
|
||||
# 需要多个英雄
|
||||
Our story needs more heroes.
|
||||
We’ll expand our Tour of Heroes app to display a list of heroes,
|
||||
allow the user to select a hero, and display the hero’s details.
|
||||
|
||||
我们的故事需要更多的英雄。我们将扩展我们的《英雄指南》,来显示一个英雄列表,运行用户选择一个英雄,并且显示英雄的详情。
|
||||
我们的故事需要更多的英雄了。我们将扩展这个《英雄指南》,来显示一个英雄列表,允许用户选择一个英雄,并且显示英雄的详情。
|
||||
|
||||
[Run the live example for part 2](/resources/live-examples/toh-2/ts/plnkr.html)
|
||||
|
||||
@ -17,8 +17,8 @@ include ../_util-fns
|
||||
First, we need a list of heroes. We want to display those heroes in the view’s template,
|
||||
so we’ll need a way to do that.
|
||||
|
||||
我们来清点一下显示英雄列表都需要点什么。
|
||||
首先,我们需要一个英雄列表数据。我们还要把这些英雄显示到一个视图的模板中,所以,我们需要用某种途径来做到这一点。
|
||||
我们来盘点一下显示英雄列表都需要些什么。
|
||||
首先,我们需要一份英雄列表数据。我们还要把这些英雄显示到一个视图的模板中,所以,我们需要用某种途径来做到这一点。
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
@ -28,7 +28,7 @@ include ../_util-fns
|
||||
let’s verify we have the following structure after [Part 1](./toh-pt1.html).
|
||||
If not, we’ll need to go back to Part 1 and figure out what we missed.
|
||||
|
||||
在继续《英雄指南》的第二部分之前,我们先检查一下,完成[第一部分](./toh-pt1.html)之后,你是否已经有了如下目录结构。如果没有,你得先回到第一部分,看看缺了哪里。
|
||||
在继续《英雄指南》的第二部分之前,我们先检查一下,完成[第一部分](./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 let’s take small steps
|
||||
first and display mock heroes.
|
||||
|
||||
`HEROS`变量是一个由`Hero`类的实例构成的数组,我们在第一部分定义过它。
|
||||
我们当然希望从一个Web服务中获取这个英雄列表,但是,别急,我们得把步子迈得小一点 —— 先用一组Mock(模拟对象)出来的英雄。
|
||||
`HEROES`变量是一个由`Hero`类的实例构成的数组,我们在第一部分定义过它。
|
||||
我们当然希望从一个Web服务中获取这个英雄列表,但别急,我们得把步子迈得小一点儿 —— 先用一组Mock(模拟)出来的英雄。
|
||||
|
||||
### Exposing heroes
|
||||
### 导出英雄们
|
||||
Let’s 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`. Let’s create an unordered list in our template to display them.
|
||||
We’ll insert the following chunk of HTML below the title and above the hero details.
|
||||
|
||||
我们的组件有`heroes`属性,我们来到模板中创建一个无序列表来显示他们。
|
||||
我们的组件有了`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.
|
||||
We’ll need some help from Angular to do this. Let’s 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 hero’s properties.
|
||||
|
||||
`hero`前的`let`关键字表示`hero`是一个模板输入变量。
|
||||
在模板中,我们可以引用这个变量来存取一位英雄的属性。
|
||||
在模板中,我们可以引用这个变量来访问一位英雄的属性。
|
||||
|
||||
Learn more about `ngFor` and template input variables in the
|
||||
[Displaying Data](../guide/displaying-data.html#ngFor) and
|
||||
[Template Syntax](../guide/template-syntax.html#ngFor) chapters.
|
||||
|
||||
学习关于`ngFor`和模板输入变量的知识,参见[显示数据](../guide/displaying-data.html#ngFor)和
|
||||
[模板语法](../guide/template-syntax.html#ngFor)章节。
|
||||
要学习更多关于`ngFor`和模板输入变量的知识,参见[显示数据](../guide/displaying-data.html#ngFor)和
|
||||
[模板语法](../guide/template-syntax.html#ngFor)两章。
|
||||
|
||||
:marked
|
||||
Now we insert some content between the `<li>` tags
|
||||
that uses the `hero` template variable to display the hero’s properties.
|
||||
|
||||
现在,我们在`<li>`标记中插入一些内容,以便使用模板变量`hero`来显示英雄的属性。
|
||||
现在,我们在`<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.
|
||||
|
||||
我们的英雄列表看起来实在是稀松平常。
|
||||
但当用户的鼠标划过英雄或选中了一个英雄时,我们得让他看起来醒目一点。
|
||||
但当用户的鼠标划过英雄或选中了一个英雄时,我们得让他/他看起来醒目一点。
|
||||
|
||||
Let’s 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").
|
||||
|
||||
Let’s 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.
|
||||
That’s 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 component’s selected hero to the hero that the user clicked.
|
||||
|
||||
这个方法该做什么?它应该把组件中当前选中的英雄设置为用户刚刚点击的这个。
|
||||
这个方法该做什么?它应该把组件中被选中的英雄设置为用户刚刚点击的那个。
|
||||
|
||||
Our component doesn’t have a “selected hero” yet either. We’ll start there.
|
||||
|
||||
我们的组件还没有用来表示“当前选中的英雄”的变量,我们就从这一步开始。
|
||||
我们的组件还没有用来表示“当前选中的英雄”的变量,我们就从这一步儿开始。
|
||||
|
||||
### Expose the selected hero
|
||||
### 导出“当前选中的英雄”
|
||||
@ -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").
|
||||
We’ve decided that none of the heroes should be selected before the user picks a hero so
|
||||
we won’t initialize the `selectedHero` as we were doing with `hero`.
|
||||
|
||||
我们决定:在用户选取之前,我们不会默认选择任何英雄,所以,我们不会去像`hero`一样初始化`selectedHero`变量。
|
||||
我们已决定:在用户选取之前,不会默认选择任何英雄,所以,我们不用像`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").
|
||||
Let’s 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`.
|
||||
That’s why we'll see the following error in the browser’s 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 hero’s details
|
||||
* 我们添加了选择英雄的能力,并且会显示这个英雄的详情
|
||||
* We learned how to use the built-in directives `ngIf` and `ngFor` in a component’s 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)学到的那样。
|
||||
|
@ -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, let’s verify we have the following structure. If not, we’ll 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应用。
|
||||
|
||||
Let’s 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`.
|
||||
Let’s **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=".").
|
||||
<my-hero-detail [hero]="selectedHero"></my-hero-detail>
|
||||
:marked
|
||||
Notice that the `hero` property is the ***target*** of a property binding — 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=".").
|
||||
<my-hero-detail></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=".").
|
||||
<my-hero-detail [hero]="selectedHero"></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 hero’s details.
|
||||
|
||||
当在浏览器中查看应用时,我们看到了英雄列表。
|
||||
当选中一个英雄时,我们还能看到所选英雄的详情。
|
||||
当选中一个英雄时,还能看到所选英雄的详情。
|
||||
|
||||
What's fundamentally new is that we can use this `HeroDetailComponent`
|
||||
to show hero details anywhere in the app.
|
||||
|
||||
我们所关注的进步是:我们可以在应用中的任何地方使用这个`HeroDetailComponent`组件来显示英雄详情了。
|
||||
值得关注的进步是:我们可以在应用中的任何地方使用这个`HeroDetailComponent`组件来显示英雄详情了。
|
||||
|
||||
We’ve created our first reusable component!
|
||||
|
||||
@ -327,7 +328,7 @@ code-example(format=".")
|
||||
### 回顾应用结构
|
||||
Let’s 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数据。
|
||||
显然,这种方式不能“可持续发展”。
|
||||
我们要把数据访问逻辑抽取到一个独立的服务中,并在需要数据的组件之间共享。
|
||||
|
||||
We’ll learn to create services in the [next tutorial](toh-pt4.html) chapter.
|
||||
|
||||
在[下一步](toh-pt4.html)中,我们将学习如何创建服务。
|
||||
在[下一步](toh-pt4.html),我们将学习如何创建服务。
|
||||
|
@ -37,7 +37,7 @@ include ../_util-fns
|
||||
Before we continue with our Tour of Heroes, let’s verify we have the following structure.
|
||||
If not, we’ll 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`:
|
||||
|
@ -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")
|
||||
|
Loading…
x
Reference in New Issue
Block a user