把英文双引号修正为中文的

This commit is contained in:
Zhicheng Wang 2017-05-07 11:36:33 +08:00
parent 8baa278399
commit 83105da6c7
26 changed files with 172 additions and 91 deletions

View File

@ -708,7 +708,7 @@ code-example(language="none" class="code-shell").
Develop as usual. Develop as usual.
The server and TypeScript compiler are in "watch mode" so your changes are reflected immediately in the browser. The server and TypeScript compiler are in "watch mode" so your changes are reflected immediately in the browser.
照常开发。服务器和TypeScript编译器都处于"监听模式",因此我们的修改都可以立刻反映到浏览器中。 照常开发。服务器和TypeScript编译器都处于“监听模式”,因此我们的修改都可以立刻反映到浏览器中。
To see those changes in AOT, switch to the original terminal and re-run `npm run build:aot`. To see those changes in AOT, switch to the original terminal and re-run `npm run build:aot`.
When it finishes, go back to the browser and use the back button to When it finishes, go back to the browser and use the back button to

View File

@ -241,7 +241,7 @@ a#template2
Here's the hero name again, excerpted from the revised template (Template 2), next to the original version: Here's the hero name again, excerpted from the revised template (Template 2), next to the original version:
下面也是关于英雄名字的控制器,从修改后的模板("Template 2")中抽取出来,与原来的版本相比: 下面也是关于英雄名字的控制器,从修改后的模板(“Template 2”)中抽取出来,与原来的版本相比:
+makeTabs( +makeTabs(
`cb-form-validation/ts/src/app/template/hero-form-template2.component.html, `cb-form-validation/ts/src/app/template/hero-form-template2.component.html,
@ -785,9 +785,9 @@ a#custom-validation
the validator rejects any hero name containing "bob". the validator rejects any hero name containing "bob".
Elsewhere it could reject "alice" or any name that the configuring regular expression matches. Elsewhere it could reject "alice" or any name that the configuring regular expression matches.
在本例中,禁止的名字是"bob" 在本例中,禁止的名字是“bob”
验证器拒绝任何带有"bob"的英雄名字。 验证器拒绝任何带有“bob”的英雄名字。
在其他地方,只要配置的正则表达式可以匹配上,它可能拒绝"alice"或者任何其他名字。 在其他地方,只要配置的正则表达式可以匹配上,它可能拒绝“alice”或者任何其他名字。
The `forbiddenNameValidator` factory returns the configured validator function. The `forbiddenNameValidator` factory returns the configured validator function.
That function takes an Angular control object and returns _either_ That function takes an Angular control object and returns _either_

View File

@ -1516,7 +1516,7 @@ table
See also [Do you need a _Routing Module_?](../guide/router.html#why-routing-module) on the See also [Do you need a _Routing Module_?](../guide/router.html#why-routing-module) on the
[Routing & Navigation](../guide/router.html) page. [Routing & Navigation](../guide/router.html) page.
参见[路由与导航](../guide/router.html)一章的"[你需要**路由模块**吗?](../guide/router.html#why-routing-module)"部分。 参见[路由与导航](../guide/router.html)一章的“[你需要**路由模块**吗?](../guide/router.html#why-routing-module)”部分。
tr tr
td(style="vertical-align: top") <a id="service-feature-module"></a> td(style="vertical-align: top") <a id="service-feature-module"></a>

View File

@ -476,7 +476,7 @@ a#dsl
这个 _TypeScript_ "getter" 属性会翻译成 _ES5_ <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty" 这个 _TypeScript_ "getter" 属性会翻译成 _ES5_ <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty"
target="_blank" title="Defined Properties">已定义属性</a>。 target="_blank" title="Defined Properties">已定义属性</a>。
_ES5 DSL_ 不直接支持_已定义属性_你仍可提取"类"原型象下面这样添加_已定义属性_ _ES5 DSL_ 不直接支持_已定义属性_你仍可提取“类”原型象下面这样添加_已定义属性_
+makeExample('cb-ts-to-js/js/src/app/hero-queries.component.js', 'defined-property','js/src/app/hero-queries.component.ts')(format='.') +makeExample('cb-ts-to-js/js/src/app/hero-queries.component.js', 'defined-property','js/src/app/hero-queries.component.ts')(format='.')

View File

@ -977,7 +977,7 @@ figure
> It displays a price of 42.33 as `$42.33`. > It displays a price of 42.33 as `$42.33`.
> 它把价格"42.33"显示为`$42.33`。 > 它把价格“42.33”显示为`$42.33`。
> [**Router**](router.html): Navigate from page to page within the client > [**Router**](router.html): Navigate from page to page within the client
application and never leave the browser. application and never leave the browser.

View File

@ -13,7 +13,7 @@ block includes
## All mention of moduleId removed. "Component relative paths" cookbook deleted (2017-03-13) ## All mention of moduleId removed. "Component relative paths" cookbook deleted (2017-03-13)
## 移除了所有的moduleId引用。移除了"组件相对路径" 的烹饪书。(2017-03-13) ## 移除了所有的moduleId引用。移除了“组件相对路径” 的烹饪书。(2017-03-13)
We added a new SystemJS plugin (systemjs-angular-loader.js) to our recommended SystemJS configuration. We added a new SystemJS plugin (systemjs-angular-loader.js) to our recommended SystemJS configuration.
This plugin dynamically converts "component-relative" paths in templateUrl and styleUrls to "absolute paths" for you. This plugin dynamically converts "component-relative" paths in templateUrl and styleUrls to "absolute paths" for you.
@ -35,7 +35,7 @@ block includes
Look for the new download links next to the "live example" links. Look for the new download links next to the "live example" links.
现在你可以为任何一篇指南下载范例程序,并且在本地运行它了。 现在你可以为任何一篇指南下载范例程序,并且在本地运行它了。
请在"在线例子"的链接后面查找新的下载链接。 请在“在线例子”的链接后面查找新的下载链接。
## Template Syntax/Structural Directives: refreshed (2017-02-06) ## Template Syntax/Structural Directives: refreshed (2017-02-06)
@ -246,12 +246,12 @@ block includes
## ES6 described in "TypeScript to JavaScript" (2016-11-14) ## ES6 described in "TypeScript to JavaScript" (2016-11-14)
## 在"从TypeScript到JavaScript"增加ES6的描述 (2016-11-14) ## 在“从TypeScript到JavaScript”增加ES6的描述 (2016-11-14)
The updated [TypeScript to JavaScript](../cookbook/ts-to-js.html) cookbook The updated [TypeScript to JavaScript](../cookbook/ts-to-js.html) cookbook
now explains how to write apps in ES6/7 now explains how to write apps in ES6/7
更新了"[从TypeScript到JavaScript](../cookbook/ts-to-js.html)"烹饪宝典解释如何使用ES6/7编写应用 更新了“[从TypeScript到JavaScript](../cookbook/ts-to-js.html)”烹饪宝典解释如何使用ES6/7编写应用
by translating the common idioms in the TypeScript documentation examples by translating the common idioms in the TypeScript documentation examples
(and elsewhere on the web) to ES6/7 and ES5. (and elsewhere on the web) to ES6/7 and ES5.

View File

@ -106,7 +106,7 @@ block includes
* [Non-class dependencies](#non-class-dependencies) * [Non-class dependencies](#non-class-dependencies)
[非"类"依赖](#non-class-dependencies) [非“类”依赖](#non-class-dependencies)
* [`InjectionToken`](#injection-token) * [`InjectionToken`](#injection-token)

View File

@ -285,7 +285,7 @@ a#node-modules
1. Add the "Simple deployment" sample files shown above. 1. Add the "Simple deployment" sample files shown above.
添加上述的"简单部署"范例文件。 添加上述的“简单部署”范例文件。
1. Run it with `npm start` as you would any project. 1. Run it with `npm start` as you would any project.
@ -520,7 +520,7 @@ a#measure
You can waste a lot of time and money optimizing something that has no tangible benefit or even makes the app slower. You can waste a lot of time and money optimizing something that has no tangible benefit or even makes the app slower.
You should measure the app's actual behavior when running in the environments that are important to you. You should measure the app's actual behavior when running in the environments that are important to you.
如果我们能对"是什么导致了应用变慢"的问题有一个清晰、准确的理解,那就可以对优化什么、如何优化做出更好地决策了。 如果我们能对“是什么导致了应用变慢”的问题有一个清晰、准确的理解,那就可以对优化什么、如何优化做出更好地决策了。
真正的原因可能并不是你所想的那样。 真正的原因可能并不是你所想的那样。
我们可能花费大量的时间和金钱去优化一些东西,但它却无法产生可感知的效果甚至让应用变得更慢。 我们可能花费大量的时间和金钱去优化一些东西,但它却无法产生可感知的效果甚至让应用变得更慢。
我们应该在那些最重要的环境中实际运行,来度量应用的实际行为。 我们应该在那些最重要的环境中实际运行,来度量应用的实际行为。
@ -702,7 +702,7 @@ a#deep-link
For example, `http://www.mysite.com/heroes/42` is a _deep link_ to the hero detail page For example, `http://www.mysite.com/heroes/42` is a _deep link_ to the hero detail page
that displays the hero with `id: 42`. that displays the hero with `id: 42`.
带路由的应用应该支持"深链接" 带路由的应用应该支持“深链接”
所谓*深链接*就是指一个URL它用于指定到应用内某个组件的路径。 所谓*深链接*就是指一个URL它用于指定到应用内某个组件的路径。
比如,`http://www.mysite.com/heroes/42`就是一个到英雄详情页面的*深链接*,用于显示`id: 42`的英雄。 比如,`http://www.mysite.com/heroes/42`就是一个到英雄详情页面的*深链接*,用于显示`id: 42`的英雄。

View File

@ -247,7 +247,7 @@ figure.image-display
* The `@Component` selector value of "hero-form" means you can drop this form in a parent template with a `<hero-form>` tag. * The `@Component` selector value of "hero-form" means you can drop this form in a parent template with a `<hero-form>` tag.
`@Component`选择器"hero-form"表示可以用`<hero-form>`标签把这个表单放进父模板。 `@Component`选择器“hero-form”表示可以用`<hero-form>`标签把这个表单放进父模板。
* The `templateUrl` property points to a separate file for the template HTML. * The `templateUrl` property points to a separate file for the template HTML.
@ -357,7 +357,7 @@ figure.image-display
Replace the contents of the "QuickStart" version with the following: Replace the contents of the "QuickStart" version with the following:
"快速起步"的版本内容替换成下列代码: “快速起步”的版本内容替换成下列代码:
+makeExample('src/app/app.component.ts') +makeExample('src/app/app.component.ts')
@ -975,8 +975,8 @@ figure.image-display
`#heroForm`, and initialized it with the value "ngForm". `#heroForm`, and initialized it with the value "ngForm".
Now, use that variable to access the form with the Submit button. Now, use that variable to access the form with the Submit button.
我们已经定义了一个模板引用变量`#heroForm`,并且把赋值为"ngForm" 我们已经定义了一个模板引用变量`#heroForm`,并且把赋值为“ngForm”
现在,就可以在"Submit"按钮中访问这个表单了。 现在,就可以在“Submit”按钮中访问这个表单了。
:marked :marked
You'll bind the form's overall validity via You'll bind the form's overall validity via

View File

@ -113,7 +113,7 @@ figure.image-display
服务解析逻辑会自下而上查找,碰到的第一个提供商会胜出。 服务解析逻辑会自下而上查找,碰到的第一个提供商会胜出。
因此,注入器树中间层注入器上的提供商,可以拦截来自底层的对特定服务的请求。 因此,注入器树中间层注入器上的提供商,可以拦截来自底层的对特定服务的请求。
这导致它可以"重新配置"和者说"遮蔽"高层的注入器。 这导致它可以“重新配置”和者说“遮蔽”高层的注入器。
If you only specify providers at the top level (typically the root `AppModule`), the tree of injectors appears to be flat. If you only specify providers at the top level (typically the root `AppModule`), the tree of injectors appears to be flat.
All requests bubble up to the root <code>NgModule</code> injector that you configured with the `bootstrapModule` method. All requests bubble up to the root <code>NgModule</code> injector that you configured with the `bootstrapModule` method.

View File

@ -16,7 +16,7 @@ block includes
If you're new to Angular, you may want to visit "[Learning Angular](learning-angular.html)" first. If you're new to Angular, you may want to visit "[Learning Angular](learning-angular.html)" first.
本页是 Angular 文档的概述。 本页是 Angular 文档的概述。
如果你刚接触 Angular请先访问"[学习 Angular](learning-angular.html)" 如果你刚接触 Angular请先访问“[学习 Angular](learning-angular.html)”
## Themes ## Themes

View File

@ -73,4 +73,4 @@ figure
Try the [tutorial](../tutorial "Tour of Heroes") if you're ready to start coding or Try the [tutorial](../tutorial "Tour of Heroes") if you're ready to start coding or
visit the [Architecture](architecture.html "Basic Concepts") page if you prefer to learn the basic concepts first. visit the [Architecture](architecture.html "Basic Concepts") page if you prefer to learn the basic concepts first.
如果你想开始编程,那就试试[教程](../tutorial "英雄指南")。或者如果你想要先学习基本概念,那么阅读[架构](architecture.html "基本概念")页面。 如果你想开始编程,那就试试[教程](../tutorial “英雄指南”)。或者如果你想要先学习基本概念,那么阅读[架构](architecture.html “基本概念”)页面。

View File

@ -305,26 +305,26 @@ a(id="why-peer-dependencies")
Two packages, "A" and "B", could depend on the same third package "C". Two packages, "A" and "B", could depend on the same third package "C".
"A" and "B" might both list "C" among their *dependencies*. "A" and "B" might both list "C" among their *dependencies*.
两个包,"A"和"B",可能依赖共同的第三个包"C" 两个包,“A”和“B”可能依赖共同的第三个包“C”
"A"和"B"可能都在它们的*dependencies*中列出了"C" "A"和“B”可能都在它们的*dependencies*中列出了“C”
What if "A" and "B" depend on different versions of "C" ("C1" and "C2"). The npm package system supports that. What if "A" and "B" depend on different versions of "C" ("C1" and "C2"). The npm package system supports that.
It installs "C1" in the `node_modules` folder for "A" and "C2" in the `node_modules` folder for "B". It installs "C1" in the `node_modules` folder for "A" and "C2" in the `node_modules` folder for "B".
Now "A" and "B" have their own copies of "C" and they run without interferring with one another. Now "A" and "B" have their own copies of "C" and they run without interferring with one another.
如果"A"和"B"依赖于"C"的不同版本("C1"和"C2")。npm包管理系统也能支持 如果“A”和“B”依赖于“C”的不同版本("C1"和“C2”)。npm包管理系统也能支持
它会把"C1"安装到"A"的`node_modules`目录下给"A"用,把"C2"安装到"B"的`node_modules`目录下给"B"用。 它会把“C1”安装到“A”的`node_modules`目录下给“A”用把“C2”安装到“B”的`node_modules`目录下给“B”用。
现在,"A"和"B"都有了它们自己的一份"C"的复本,它们运行起来也互不干扰。 现在,“A”和“B”都有了它们自己的一份“C”的复本,它们运行起来也互不干扰。
But there is a problem. Package "A" may require the presence of "C1" without actually calling upon it directly. But there is a problem. Package "A" may require the presence of "C1" without actually calling upon it directly.
"A" may only work if *everyone is using "C1"*. It falls down if any part of the application relies on "C2". "A" may only work if *everyone is using "C1"*. It falls down if any part of the application relies on "C2".
但是有一个问题。包"A"可能只需要"C1"出现就行,而实际上并不会直接调用它。 但是有一个问题。包“A”可能只需要“C1”出现就行,而实际上并不会直接调用它。
"A"可能只有当*每个人都使用"C1"时*才能正常工作。如果程序中的任何一个部分依赖了"C2",它就会失败。 "A"可能只有当*每个人都使用“C1”时*才能正常工作。如果程序中的任何一个部分依赖了“C2”,它就会失败。
The solution is for "A" to declare that "C1" is a *peer dependency*. The solution is for "A" to declare that "C1" is a *peer dependency*.
要想解决这个问题,"A"就需要把"C1"定义为它的*平级依赖*。 要想解决这个问题,“A”就需要把“C1”定义为它的*平级依赖*。
The difference between a `dependency` and a `peerDependency` is roughly this: The difference between a `dependency` and a `peerDependency` is roughly this:

View File

@ -152,7 +152,7 @@ block includes
"**<samp>04/15/1988</samp>**" and "**<samp>04/15/1988</samp>**" and
"**<samp>Friday, April 15, 1988</samp>**". "**<samp>Friday, April 15, 1988</samp>**".
当我们点击按钮的时候,显示的日志会在"**<samp>04/15/1988</samp>**"和"**<samp>Friday, April 15, 1988</samp>**"之间切换。 当我们点击按钮的时候,显示的日志会在“**<samp>04/15/1988</samp>**”和“**<samp>Friday, April 15, 1988</samp>**”之间切换。
figure.image-display figure.image-display
img(src='/resources/images/devguide/pipes/date-format-toggle-anim.gif' alt="Date Format Toggle") img(src='/resources/images/devguide/pipes/date-format-toggle-anim.gif' alt="Date Format Toggle")

View File

@ -5,7 +5,7 @@ include ../_util-fns
This guide explains reactive forms as you follow the steps to build a "Hero Detail Editor" form. This guide explains reactive forms as you follow the steps to build a "Hero Detail Editor" form.
*响应式表单*是Angular中用*响应式*风格创建表单的技术。 *响应式表单*是Angular中用*响应式*风格创建表单的技术。
本章中,我们会在构建"英雄详情编辑器"的过程中,逐步讲解响应式表单的概念。 本章中,我们会在构建“英雄详情编辑器”的过程中,逐步讲解响应式表单的概念。
a#toc a#toc
:marked :marked
@ -221,7 +221,7 @@ a#async-vs-sync
from within the component class. from within the component class.
模板驱动表单会委托指令来创建它们的表单控件。 模板驱动表单会委托指令来创建它们的表单控件。
为了消除"检查完后又变化了"的错误,这些指令需要消耗一个以上的变更检测周期来构建整个控件树。 为了消除“检查完后又变化了”的错误,这些指令需要消耗一个以上的变更检测周期来构建整个控件树。
这意味着在从组件类中操纵任何控件之前,我们都必须先等待一个节拍。 这意味着在从组件类中操纵任何控件之前,我们都必须先等待一个节拍。
For example, if you inject the form control with a `@ViewChild(NgForm)` query and examine it in the For example, if you inject the form control with a `@ViewChild(NgForm)` query and examine it in the
@ -252,7 +252,7 @@ a#async-vs-sync
Choose the approach that works best for you. Choose the approach that works best for you.
You may decide to use both in the same application. You may decide to use both in the same application.
没有哪个"更好" 没有哪个“更好”
它们是两种架构范式,各有优缺点。 它们是两种架构范式,各有优缺点。
请自行选择更合适的方法,甚至可以在同一个应用中同时使用它们。 请自行选择更合适的方法,甚至可以在同一个应用中同时使用它们。
@ -1531,9 +1531,9 @@ a#form-array
务必确保**添加了`type="button"`属性**。 务必确保**添加了`type="button"`属性**。
事实上,我们应该总是指定按钮的`type`。 事实上,我们应该总是指定按钮的`type`。
如果不明确指定类型,按钮的默认类型就是"submit"(提交)。 如果不明确指定类型,按钮的默认类型就是“submit”(提交)。
当我们稍后添加了*表单提交*的动作时,每个"submit"按钮都是触发一次提交操作,而它将可能会做一些处理,比如保存当前的修改。 当我们稍后添加了*表单提交*的动作时,每个“submit”按钮都是触发一次提交操作,而它将可能会做一些处理,比如保存当前的修改。
我们显然不会希望每当用户点击"Add a Secret Lair"按钮时就保存一次。 我们显然不会希望每当用户点击“Add a Secret Lair”按钮时就保存一次。
:marked :marked
### Try it! ### Try it!
@ -1543,7 +1543,7 @@ a#form-array
Back in the browser, select the hero named "Magneta". Back in the browser, select the hero named "Magneta".
"Magneta" doesn't have an address, as you can see in the diagnostic JSON at the bottom of the form. "Magneta" doesn't have an address, as you can see in the diagnostic JSON at the bottom of the form.
回到浏览器中,选择名叫"Magneta"的英雄。 回到浏览器中,选择名叫“Magneta”的英雄。
"Magneta"没有地址我们会在表单底部的诊断用JSON中看到这一点。 "Magneta"没有地址我们会在表单底部的诊断用JSON中看到这一点。
figure.image-display figure.image-display
@ -1553,7 +1553,7 @@ figure.image-display
Click the "_Add a Secret Lair_" button. Click the "_Add a Secret Lair_" button.
A new address section appears. Well done! A new address section appears. Well done!
点击"Add a Secret Lair"按钮,一个新的地址区就出现了,干得好! 点击“Add a Secret Lair”按钮,一个新的地址区就出现了,干得好!
### Remove a lair ### Remove a lair
@ -1617,7 +1617,7 @@ a#observe-control
Return to the browser, select a hero (e.g, "Magneta"), and start typing in the _name_ input box. Return to the browser, select a hero (e.g, "Magneta"), and start typing in the _name_ input box.
You should see a new name in the log after each keystroke. You should see a new name in the log after each keystroke.
返回浏览器,选择一个英雄(比如"Magneta"),并开始在*姓名*输入框中键入。 返回浏览器,选择一个英雄(比如“Magneta”),并开始在*姓名*输入框中键入。
我们会看到,每次按键都会记录一个新名字。 我们会看到,每次按键都会记录一个新名字。
### When to use it ### When to use it
@ -1715,21 +1715,21 @@ figure.image-display
Add the "Save" and "Revert" buttons near the top of the component's template: Add the "Save" and "Revert" buttons near the top of the component's template:
"Save"和"Revert"按钮添加到组件模板的顶部: “Save”和“Revert”按钮添加到组件模板的顶部:
+makeExample('reactive-forms/ts/src/app/hero-detail.component.html', 'buttons','src/app/hero-detail.component.html (Save and Revert buttons)')(format=".") +makeExample('reactive-forms/ts/src/app/hero-detail.component.html', 'buttons','src/app/hero-detail.component.html (Save and Revert buttons)')(format=".")
:marked :marked
The buttons are disabled until the user "dirties" the form by changing a value in any of its form controls (`heroForm.dirty`). The buttons are disabled until the user "dirties" the form by changing a value in any of its form controls (`heroForm.dirty`).
这些按钮默认是禁用的,直到用户通过修改任何一个表单控件的值"弄脏"了表单中的数据(即`heroForm.dirty`)。 这些按钮默认是禁用的,直到用户通过修改任何一个表单控件的值“弄脏”了表单中的数据(即`heroForm.dirty`)。
Clicking a button of type `"submit"` triggers the `ngSubmit` event which calls the component's `onSubmit` method. Clicking a button of type `"submit"` triggers the `ngSubmit` event which calls the component's `onSubmit` method.
Clicking the revert button triggers a call to the component's `revert` method. Clicking the revert button triggers a call to the component's `revert` method.
Users now can save or revert changes. Users now can save or revert changes.
点击一个类型为`"submit"`的按钮会触发`ngSubmit`事件,而它会调用组件的`onSubmit`方法。 点击一个类型为`"submit"`的按钮会触发`ngSubmit`事件,而它会调用组件的`onSubmit`方法。
点击"Revert"按钮则会调用组件的`revert`方法。 点击“Revert”按钮则会调用组件的`revert`方法。
现在,用户可以保存或放弃修改了。 现在,用户可以保存或放弃修改了。
This is the final step in the demo. This is the final step in the demo.

View File

@ -496,7 +496,7 @@ a#example-config
This is useful for displaying a "404 - Not Found" page or redirecting to another route. This is useful for displaying a "404 - Not Found" page or redirecting to another route.
最后一个路由中的`**`路径是一个**通配符**。当所请求的URL不匹配前面定义的路由表中的任何路径时路由器就会选择此路由。 最后一个路由中的`**`路径是一个**通配符**。当所请求的URL不匹配前面定义的路由表中的任何路径时路由器就会选择此路由。
这个特性可用于显示"404 - Not Found"页,或自动重定向到其它路由。 这个特性可用于显示“404 - Not Found”页,或自动重定向到其它路由。
**The order of the routes in the configuration matters** and this is by design. The router uses a **first-match wins** **The order of the routes in the configuration matters** and this is by design. The router uses a **first-match wins**
strategy when matching routes, so more specific routes should be placed above less specific routes. strategy when matching routes, so more specific routes should be placed above less specific routes.
@ -546,7 +546,7 @@ a#basics-router-links
The navigation paths are fixed, so you can assign a string to the `routerLink` (a "one-time" binding). The navigation paths are fixed, so you can assign a string to the `routerLink` (a "one-time" binding).
`a`标签上的`RouterLink`指令让路由器得以控制这个`a`元素。 `a`标签上的`RouterLink`指令让路由器得以控制这个`a`元素。
这里的导航路径是固定的,因此可以把一个字符串赋给`routerLink`"一次性"绑定)。 这里的导航路径是固定的,因此可以把一个字符串赋给`routerLink`“一次性”绑定)。
Had the navigation path been more dynamic, you could have bound to a template expression that Had the navigation path been more dynamic, you could have bound to a template expression that
returned an array of route link parameters (the _link parameters array_). returned an array of route link parameters (the _link parameters array_).
@ -559,7 +559,7 @@ a#basics-router-links
The router adds the `active` CSS class to the element when the associated *RouterLink* becomes active. The router adds the `active` CSS class to the element when the associated *RouterLink* becomes active.
You can add this directive to the anchor or to its parent element. You can add this directive to the anchor or to its parent element.
每个`a`标签上的**`RouterLinkActive`**指令可以帮用户在外观上区分出当前选中的"活动"路由。 每个`a`标签上的**`RouterLinkActive`**指令可以帮用户在外观上区分出当前选中的“活动”路由。
当与它关联的*RouterLink*被激活时路由器会把CSS类`active`添加到这个元素上。 当与它关联的*RouterLink*被激活时路由器会把CSS类`active`添加到这个元素上。
我们可以把该指令添加到`a`元素或它的父元素上。 我们可以把该指令添加到`a`元素或它的父元素上。
@ -731,11 +731,11 @@ a#sample-app-intro
* Navigating to a component (*Heroes* link to "Heroes List"). * Navigating to a component (*Heroes* link to "Heroes List").
导航到组件(*Heroes*链接到"英雄列表"组件)。 导航到组件(*Heroes*链接到“英雄列表”组件)。
* Including a route parameter (passing the Hero `id` while routing to the "Hero Detail"). * Including a route parameter (passing the Hero `id` while routing to the "Hero Detail").
包含一个路由参数(当路由到"英雄详情"时,把该英雄的`id`传进去)。 包含一个路由参数(当路由到“英雄详情”时,把该英雄的`id`传进去)。
* Child routes (the *Crisis Center* has its own routes). * Child routes (the *Crisis Center* has its own routes).
@ -1206,7 +1206,7 @@ a#wildcard
可以添加一个**通配符**路由来拦截所有无效的URL并优雅的处理它们。 可以添加一个**通配符**路由来拦截所有无效的URL并优雅的处理它们。
*通配符*路由的`path`是两个星号(`**`),它会匹配*任何* URL。 *通配符*路由的`path`是两个星号(`**`),它会匹配*任何* URL。
当路由器匹配不上以前定义的那些路由时,它就会选择*这个*路由。 当路由器匹配不上以前定义的那些路由时,它就会选择*这个*路由。
通配符路由可以导航到自定义的"404 Not Found"组件,也可以[重定向](#redirect)到一个现有路由。 通配符路由可以导航到自定义的“404 Not Found”组件,也可以[重定向](#redirect)到一个现有路由。
.l-sub-section .l-sub-section
:marked :marked
@ -1231,7 +1231,7 @@ a#wildcard
Instead of adding the `"/sidekicks"` route, define a `wildcard` route instead and have it navigate to a simple `PageNotFoundComponent`. Instead of adding the `"/sidekicks"` route, define a `wildcard` route instead and have it navigate to a simple `PageNotFoundComponent`.
不要添加`"/sidekicks"`路由,而是定义一个"通配符"路由,让它直接导航到`PageNotFoundComponent`组件。 不要添加`"/sidekicks"`路由,而是定义一个“通配符”路由,让它直接导航到`PageNotFoundComponent`组件。
+makeExcerpt('src/app/app.module.1.ts', 'wildcard') +makeExcerpt('src/app/app.module.1.ts', 'wildcard')
@ -1250,7 +1250,7 @@ a#wildcard
Now when the user visits `/sidekicks`, or any other invalid URL, the browser displays "Page not found". Now when the user visits `/sidekicks`, or any other invalid URL, the browser displays "Page not found".
The browser address bar continues to point to the invalid URL. The browser address bar continues to point to the invalid URL.
现在,当用户访问`/sidekicks`或任何无效的URL时浏览器就会显示"Page not found" 现在,当用户访问`/sidekicks`或任何无效的URL时浏览器就会显示“Page not found”
浏览器的地址栏仍指向无效的URL。 浏览器的地址栏仍指向无效的URL。
a#default-route a#default-route
@ -1276,7 +1276,7 @@ code-example.
It would be nicer if the application had a **default route** that displayed the list of heroes immediately, It would be nicer if the application had a **default route** that displayed the list of heroes immediately,
just as it will when the user clicks the "Heroes" link or pastes `localhost:3000/heroes` into the address bar. just as it will when the user clicks the "Heroes" link or pastes `localhost:3000/heroes` into the address bar.
如果应用有一个*默认路由*显然会更好,它会立即显示英雄列表,就像用户点击了"Heroes"链接或者把`localhost:3000/heroes`粘贴进地址栏一样。 如果应用有一个*默认路由*显然会更好,它会立即显示英雄列表,就像用户点击了“Heroes”链接或者把`localhost:3000/heroes`粘贴进地址栏一样。
a#redirect a#redirect
:marked :marked
@ -1333,8 +1333,8 @@ a#redirect
_Every_ URL, good or bad, that falls through to _this_ route definition _Every_ URL, good or bad, that falls through to _this_ route definition
will be a match. will be a match.
尝试把它设置为`'prefix'`,然后点击`Go to sidekicks`按钮。别忘了它是一个无效URL本应显示"Page not found"页。 尝试把它设置为`'prefix'`,然后点击`Go to sidekicks`按钮。别忘了它是一个无效URL本应显示“Page not found”页。
但是,我们看到了"英雄列表"页。在地址栏中输入一个无效的URL我们又被路由到了`/heroes`。 但是,我们看到了“英雄列表”页。在地址栏中输入一个无效的URL我们又被路由到了`/heroes`。
*每一个*URL无论有效与否都会匹配上这个路由定义。 *每一个*URL无论有效与否都会匹配上这个路由定义。
The default route should redirect to the `HeroListComponent` _only_ when the _entire_ url is `''`. The default route should redirect to the `HeroListComponent` _only_ when the _entire_ url is `''`.
@ -1601,7 +1601,7 @@ a#why-routing-module
and you'll be copying much of the code and you'll be copying much of the code
from the <live-example name="toh-4" title="Tour of Heroes: Services example code"></live-example>. from the <live-example name="toh-4" title="Tour of Heroes: Services example code"></live-example>.
这个例子重写了[《英雄指南》](../tutorial/toh-pt4.html "Tour of Heroes: Services")的"服务"部分的英雄列表特性,我们可以从<live-example name="toh-4" title="Tour of Heroes: Services example code"></live-example>中赋值大部分代码过来。 这个例子重写了[《英雄指南》](../tutorial/toh-pt4.html "Tour of Heroes: Services")的“服务”部分的英雄列表特性,我们可以从<live-example name="toh-4" title="Tour of Heroes: Services example code"></live-example>中赋值大部分代码过来。
Here's how the user will experience this version of the app: Here's how the user will experience this version of the app:
@ -1654,7 +1654,7 @@ a#heroes-functionality
* Copy into it the contents of the `app.component.ts` from * Copy into it the contents of the `app.component.ts` from
the <live-example name="toh-4" title="Tour of Heroes: Services example code">"Services" tutorial</live-example>. the <live-example name="toh-4" title="Tour of Heroes: Services example code">"Services" tutorial</live-example>.
把<live-example name="toh-4" title="Tour of Heroes: Services example code">教程中的"服务"部分</live-example>的代码复制到`app.component.ts`中。 把<live-example name="toh-4" title="Tour of Heroes: Services example code">教程中的“服务”部分</live-example>的代码复制到`app.component.ts`中。
* Make a few minor but necessary changes: * Make a few minor but necessary changes:
@ -1759,7 +1759,7 @@ a#hero-routing-module
Import the hero components from their new locations in the `src/app/heroes/` folder, define the two hero routes, Import the hero components from their new locations in the `src/app/heroes/` folder, define the two hero routes,
and export the `HeroRoutingModule` class. and export the `HeroRoutingModule` class.
从新位置`src/app/heroes/`目录中导入英雄相关的组件,定义两个"英雄管理"路由,并导出`HeroRoutingModule`类。 从新位置`src/app/heroes/`目录中导入英雄相关的组件,定义两个“英雄管理”路由,并导出`HeroRoutingModule`类。
Now that you have routes for the `Heroes` module, register them with the `Router` via the Now that you have routes for the `Heroes` module, register them with the `Router` via the
`RouterModule` _almost_ as you did in the `AppRoutingModule`. `RouterModule` _almost_ as you did in the `AppRoutingModule`.
@ -1808,7 +1808,7 @@ a#remove-duplicate-hero-routes
:marked :marked
### Remove duplicate hero routes ### Remove duplicate hero routes
### 移除重复的"英雄管理"路由 ### 移除重复的“英雄管理”路由
The hero routes are currently defined in _two_ places: in the `HeroesRoutingModule`, The hero routes are currently defined in _two_ places: in the `HeroesRoutingModule`,
by way of the `HeroesModule`, and in the `AppRoutingModule`. by way of the `HeroesModule`, and in the `AppRoutingModule`.
@ -1838,7 +1838,7 @@ a#merge-hero-routes
:marked :marked
### Import hero module into AppModule ### Import hero module into AppModule
### 把"英雄管理"模块导入到AppModule ### 把“英雄管理”模块导入到AppModule
The heroes feature module is ready, but the application doesn't know about the `HeroesModule` yet. The heroes feature module is ready, but the application doesn't know about the `HeroesModule` yet.
Open `app.module.ts` and revise it as follows. Open `app.module.ts` and revise it as follows.
@ -1863,8 +1863,8 @@ a#merge-hero-routes
You can evolve the hero feature with more components and different routes. You can evolve the hero feature with more components and different routes.
That's a key benefit of creating a separate module for each feature area. That's a key benefit of creating a separate module for each feature area.
最终,`AppModule`不再了解那些特定于"英雄"特性的知识,比如它的组件、路由细节等。 最终,`AppModule`不再了解那些特定于“英雄”特性的知识,比如它的组件、路由细节等。
我们可以让"英雄"特性独立演化,添加更多的组件或各种各样的路由。 我们可以让“英雄”特性独立演化,添加更多的组件或各种各样的路由。
这是我们为每个特性区创建独立模块后获得的核心优势。 这是我们为每个特性区创建独立模块后获得的核心优势。
After these steps, the `AppModule` should look like this: After these steps, the `AppModule` should look like this:
@ -1899,7 +1899,7 @@ a#routing-module-order
hitting the wildcard route and navigating to "Page not found". hitting the wildcard route and navigating to "Page not found".
当所有路由都在同一个`AppRoutingModule`时,我们要把默认路由和[通配符路由](#wildcard)放在最后(这里是在`/heroes`路由后面), 当所有路由都在同一个`AppRoutingModule`时,我们要把默认路由和[通配符路由](#wildcard)放在最后(这里是在`/heroes`路由后面),
这样路由器才有机会匹配到`/heroes`路由,否则它就会先遇到并匹配上该通配符路由,并导航到"页面未找到"路由。 这样路由器才有机会匹配到`/heroes`路由,否则它就会先遇到并匹配上该通配符路由,并导航到“页面未找到”路由。
The routes are no longer in one file. The routes are no longer in one file.
They are distributed across two modules, `AppRoutingModule` and `HeroesRoutingModule`. They are distributed across two modules, `AppRoutingModule` and `HeroesRoutingModule`.
@ -1913,8 +1913,8 @@ a#routing-module-order
will intercept the attempt to navigate to a hero route. will intercept the attempt to navigate to a hero route.
每个路由模块都会根据*导入的顺序*把自己的路由配置追加进去。 每个路由模块都会根据*导入的顺序*把自己的路由配置追加进去。
如果我们先列出了`AppRoutingModule`,那么通配符路由就会被注册在"英雄管理"路由*之前*。 如果我们先列出了`AppRoutingModule`,那么通配符路由就会被注册在“英雄管理”路由*之前*。
通配符路由(它匹配*任意*URL将会拦截住每一个到"英雄管理"路由的导航,因此事实上屏蔽了所有"英雄管理"路由。 通配符路由(它匹配*任意*URL将会拦截住每一个到“英雄管理”路由的导航,因此事实上屏蔽了所有“英雄管理”路由。
.l-sub-section .l-sub-section
:marked :marked
@ -1923,7 +1923,7 @@ a#routing-module-order
Learn about inspecting the runtime router configuration Learn about inspecting the runtime router configuration
[below](#inspect-config "Inspect the router config"). [below](#inspect-config "Inspect the router config").
反转路由模块的导入顺序,我们就会看到当点击英雄相关的链接时被导向了"页面未找到"路由。 反转路由模块的导入顺序,我们就会看到当点击英雄相关的链接时被导向了“页面未找到”路由。
要学习如何在运行时查看路由器配置,参见[稍后的内容](#inspect-config "Inspect the router config")。 要学习如何在运行时查看路由器配置,参见[稍后的内容](#inspect-config "Inspect the router config")。
a#route-def-with-parameter a#route-def-with-parameter
@ -2765,7 +2765,7 @@ a#milestone-4
Begin by imitating the heroes feature: Begin by imitating the heroes feature:
我们先从模仿"英雄管理"中的特性开始: 我们先从模仿“英雄管理”中的特性开始:
* Delete the placeholder crisis center file. * Delete the placeholder crisis center file.
@ -2781,7 +2781,7 @@ a#milestone-4
* In the new files, change every mention of "hero" to "crisis", and "heroes" to "crises". * In the new files, change every mention of "hero" to "crisis", and "heroes" to "crises".
在这些新文件中,把每一个对"hero"替换为"crisis",并把"heroes"替换为"crises" 在这些新文件中,把每一个对“hero”替换为“crisis”并把“heroes”替换为“crises”
You'll turn the `CrisisService` into a purveyor of mock crises instead of mock heroes: You'll turn the `CrisisService` into a purveyor of mock crises instead of mock heroes:
@ -3048,7 +3048,7 @@ a#relative-navigation
:marked :marked
The router supports directory-like syntax in a _link parameters list_ to help guide route name lookup: The router supports directory-like syntax in a _link parameters list_ to help guide route name lookup:
在*链接参数数组*中,路由器支持"目录式"语法来指导我们如何查询路由名: 在*链接参数数组*中,路由器支持“目录式”语法来指导我们如何查询路由名:
`./` or `no leading slash` is relative to the current level. `./` or `no leading slash` is relative to the current level.
@ -3087,16 +3087,25 @@ a#relative-navigation
a#nav-to-crisis a#nav-to-crisis
:marked :marked
### Navigate to crisis detail with a relative URL ### Navigate to crisis detail with a relative URL
### 用相对URL导航到危机详情
Update the *Crisis List* `onSelect` method to use relative navigation so you don't have Update the *Crisis List* `onSelect` method to use relative navigation so you don't have
to start from the top of the route configuration. to start from the top of the route configuration.
把*危机列表*的`onSelect`方法改成使用相对导航,以便我们不用每次都从路由配置的顶层开始。
You've already injected the `ActivatedRoute` that you need to compose the relative navigation path. You've already injected the `ActivatedRoute` that you need to compose the relative navigation path.
我们已经注入过了`ActivatedRoute`,我们需要它来和相对导航路径组合在一起。
+makeExcerpt('src/app/crisis-center/crisis-list.component.ts (constructor)', 'ctor') +makeExcerpt('src/app/crisis-center/crisis-list.component.ts (constructor)', 'ctor')
:marked :marked
When you visit the *Crisis Center*, the ancestor path is `/crisis-center`, When you visit the *Crisis Center*, the ancestor path is `/crisis-center`,
so you only need to add the `id` of the *Crisis Center* to the existing path. so you only need to add the `id` of the *Crisis Center* to the existing path.
当访问*危机中心*时,其祖先路径是`/crisis-center`,所以我们只需要把*危机*的`id`添加到现有路径中就可以了。
+makeExcerpt('src/app/crisis-center/crisis-list.component.ts (relative navigation)', 'onSelect') +makeExcerpt('src/app/crisis-center/crisis-list.component.ts (relative navigation)', 'onSelect')
@ -3104,66 +3113,112 @@ a#nav-to-crisis
If you were using a `RouterLink` to navigate instead of the `Router` service, you'd use the _same_ If you were using a `RouterLink` to navigate instead of the `Router` service, you'd use the _same_
link parameters array, but you wouldn't provide the object with the `relativeTo` property. link parameters array, but you wouldn't provide the object with the `relativeTo` property.
The `ActivatedRoute` is implicit in a `RouterLink` directive. The `ActivatedRoute` is implicit in a `RouterLink` directive.
如果我们用`RouterLink`来代替`Router`服务进行导航,就要使用*相同*的链接参数数组,不过不再需要提供`relativeTo`属性。
`ActivatedRoute`已经隐含在了`RouterLink`指令中。
+makeExcerpt('src/app/crisis-center/crisis-list.component.1.ts (relative routerLink)', 'relative-navigation-router-link') +makeExcerpt('src/app/crisis-center/crisis-list.component.1.ts (relative routerLink)', 'relative-navigation-router-link')
:marked :marked
Update the `gotoCrises` method of the `CrisisDetailComponent` to navigate back to the *Crisis Center* list using relative path navigation. Update the `gotoCrises` method of the `CrisisDetailComponent` to navigate back to the *Crisis Center* list using relative path navigation.
修改`CrisisDetailComponent`的`gotoCrises`方法,来使用相对路径返回*危机中心*列表。
+makeExcerpt('src/app/crisis-center/crisis-detail.component.ts (relative navigation)', 'gotoCrises-navigate') +makeExcerpt('src/app/crisis-center/crisis-detail.component.ts (relative navigation)', 'gotoCrises-navigate')
:marked :marked
Notice that the path goes up a level using the `../` syntax. Notice that the path goes up a level using the `../` syntax.
If the current crisis `id` is `3`, the resulting path back to the crisis list is `/crisis-center/;id=3;foo=foo`. If the current crisis `id` is `3`, the resulting path back to the crisis list is `/crisis-center/;id=3;foo=foo`.
注意这个路径使用了`../`语法返回上一级。
如果当前危机的`id`是`3`,那么最终返回到的路径就是`/crisis-center/;id=3;foo=foo`。
a#named-outlets a#named-outlets
.l-main-section .l-main-section
:marked :marked
### Displaying multiple routes in named outlets ### Displaying multiple routes in named outlets
### 用命名插座outlet显示多重路由
You decide to give users a way to contact the crisis center. You decide to give users a way to contact the crisis center.
When a user clicks a "Contact" button, you want to display a message in a popup view. When a user clicks a "Contact" button, you want to display a message in a popup view.
我们决定给用户提供一种方式来联系危机中心。
当用户点击“Contact”按钮时我们要在一个弹出框中显示一条消息。
The popup should stay open, even when switching between pages in the application, until the user closes it The popup should stay open, even when switching between pages in the application, until the user closes it
by sending the message or canceling. by sending the message or canceling.
Clearly you can't put the popup in the same outlet as the other pages. Clearly you can't put the popup in the same outlet as the other pages.
即使在应用中的不同页面之间切换,这个弹出框也应该始终保持打开状态,直到用户发送了消息或者手动取消。
显然,我们不能把这个弹出框跟其它放到页面放到同一个路由插座中。
Until now, you've defined a single outlet and you've nested child routes Until now, you've defined a single outlet and you've nested child routes
under that outlet to group routes together. under that outlet to group routes together.
The router only supports one primary _unnamed_ outlet per template. The router only supports one primary _unnamed_ outlet per template.
迄今为止,我们只定义过单路由插座,并且在其中嵌套了子路由以便对路由分组。
在每个模板中,路由器只能支持一个*无名*主路由插座。
A template can also have any number of _named_ outlets. A template can also have any number of _named_ outlets.
Each named outlet has its own set of routes with their own components. Each named outlet has its own set of routes with their own components.
Multiple outlets can be displaying different content, determined by different routes, all at the same time. Multiple outlets can be displaying different content, determined by different routes, all at the same time.
模板还可以有多个*命名的*路由插座。
每个命名插座都自己有一组带组件的路由。
多重插座可以在同一时间根据不同的路由来显示不同的内容。
Add an outlet named "popup" in the `AppComponent`, directly below the unnamed outlet. Add an outlet named "popup" in the `AppComponent`, directly below the unnamed outlet.
在`AppComponent`中添加一个名叫“popup”的插座就在无名插座的下方。
+makeExcerpt('src/app/app.component.4.ts', 'outlets') +makeExcerpt('src/app/app.component.4.ts', 'outlets')
:marked :marked
That's where a popup will go, once you learn how to route a popup component to it. That's where a popup will go, once you learn how to route a popup component to it.
一旦我们学会了如何把一个弹出框组件路由到该插座,那里就是将会出现弹出框的地方。
a#secondary-routes a#secondary-routes
:marked :marked
#### Secondary routes #### Secondary routes
#### 第二路由
Named outlets are the targets of _secondary routes_. Named outlets are the targets of _secondary routes_.
命名插座是*第二路由*的目标。
Secondary routes look like primary routes and you configure them the same way. Secondary routes look like primary routes and you configure them the same way.
They differ in a few key respects. They differ in a few key respects.
第二路由很像主路由,配置方式也一样。它们只有一些关键的不同点:
* They are independent of each other. * They are independent of each other.
它们彼此互不依赖。
* They work in combination with other routes. * They work in combination with other routes.
它们与其它路由组合使用。
* They are displayed in named outlets. * They are displayed in named outlets.
它们显示在命名插座中。
Create a new component named `ComposeMessageComponent` in `src/app/compose-message.component.ts`. Create a new component named `ComposeMessageComponent` in `src/app/compose-message.component.ts`.
It displays a simple form with a header, an input box for the message, It displays a simple form with a header, an input box for the message,
and two buttons, "Send" and "Cancel". and two buttons, "Send" and "Cancel".
在`src/app/compose-message.component.ts`中创建一个名叫`ComposeMessageComponent`的新组件。
它显示一个简单的表单包括一个头、一个消息输入框和两个按钮“Send”和“Cancel”。
figure.image-display figure.image-display
img(src='/resources/images/devguide/router/contact-popup.png' alt="Contact popup" width="250") img(src='/resources/images/devguide/router/contact-popup.png' alt="Contact popup" width="250")
:marked :marked
Here's the component and its template: Here's the component and its template:
下面是该组件及其模板:
+makeTabs( +makeTabs(
`router/ts/src/app/compose-message.component.ts, `router/ts/src/app/compose-message.component.ts,
@ -3176,19 +3231,33 @@ src / app / compose - message.component.html`)
It looks about the same as any other component you've seen in this guide. It looks about the same as any other component you've seen in this guide.
There are two noteworthy differences. There are two noteworthy differences.
它看起来几乎和我们以前看到的其它组件一样,但有两个值得注意的区别。
Note that the `send()` method simulates latency by waiting a second before "sending" the message and closing the popup. Note that the `send()` method simulates latency by waiting a second before "sending" the message and closing the popup.
主要`send()`方法在发送消息和关闭弹出框之前通过等待模拟了一秒钟的延迟。
The `closePopup()` method closes the popup view by navigating to the popup outlet with a `null`. The `closePopup()` method closes the popup view by navigating to the popup outlet with a `null`.
That's a peculiarity covered [below](#clear-secondary-routes). That's a peculiarity covered [below](#clear-secondary-routes).
`closePopup()`方法用把`popup`插座导航到`null`的方式关闭了弹出框。
这个奇怪的用法在[稍后的部分](#clear-secondary-routes)有讲解。
As with other application components, you add the `ComposeMessageComponent` to the `declarations` of an `NgModule`. As with other application components, you add the `ComposeMessageComponent` to the `declarations` of an `NgModule`.
Do so in the `AppModule`. Do so in the `AppModule`.
像其它组件一样,我们还要把`ComposeMessageComponent`添加到`AppModule`的`declarations`中。
a#add-secondary-route a#add-secondary-route
:marked :marked
#### Add a secondary route #### Add a secondary route
#### 添加第二路由
Open the `AppRoutingModule` and add a new `compose` route to the `appRoutes`. Open the `AppRoutingModule` and add a new `compose` route to the `appRoutes`.
打开`AppRoutingModule`,并把一个新的`compose`路由添加到`appRoutes`中。
+makeExcerpt('src/app/app-routing.module.3.ts (compose route)', 'compose') +makeExcerpt('src/app/app-routing.module.3.ts (compose route)', 'compose')
:marked :marked
@ -3196,13 +3265,25 @@ a#add-secondary-route
There's a new property, `outlet`, set to `'popup'`. There's a new property, `outlet`, set to `'popup'`.
This route now targets the popup outlet and the `ComposeMessageComponent` will display there. This route now targets the popup outlet and the `ComposeMessageComponent` will display there.
对`path`和`component`属性应该很熟悉了吧。
注意这个新的属性`outlet`被设置成了`'popup'`。
这个路由现在指向了`popup`插座,而`ComposeMessageComponent`也将显示在那里。
The user needs a way to open the popup. The user needs a way to open the popup.
Open the `AppComponent` and add a "Contact" link. Open the `AppComponent` and add a "Contact" link.
用户需要某种途径来打开这个弹出框。
打开`AppComponent`并添加一个“Contact”链接。
+makeExcerpt('src/app/app.component.4.ts', 'contact-link') +makeExcerpt('src/app/app.component.4.ts', 'contact-link')
:marked :marked
Although the `compose` route is pinned to the "popup" outlet, that's not sufficient for wiring the route to a `RouterLink` directive. Although the `compose` route is pinned to the "popup" outlet, that's not sufficient for wiring the route to a `RouterLink` directive.
You have to specify the named outlet in a _link parameters array_ and bind it to the `RouterLink` with a property binding. You have to specify the named outlet in a _link parameters array_ and bind it to the `RouterLink` with a property binding.
虽然`compose`路由被钉死在了`popup`插座上,但这仍然不足以向`RouterLink`指令表明要加载该路由。
我们还要在*链接参数数组*中指定这个命名插座,并通过属性绑定的形式把它绑定到`RouterLink`上。
The _link parameters array_ contains an object with a single `outlets` property whose value The _link parameters array_ contains an object with a single `outlets` property whose value
is another object keyed by one (or more) outlet names. is another object keyed by one (or more) outlet names.
In this case there is only the "popup" outlet property and its value is another _link parameters array_ that specifies the `compose` route. In this case there is only the "popup" outlet property and its value is another _link parameters array_ that specifies the `compose` route.

View File

@ -1097,7 +1097,7 @@ block wikipedia-jsonp+
starting with `debounceTime`, `distinctUntilChanged`, and `switchMap` operators, starting with `debounceTime`, `distinctUntilChanged`, and `switchMap` operators,
imported as [described above](#rxjs-library). imported as [described above](#rxjs-library).
虽然它们的模板几乎相同,但是这个"智能"版涉及到了更多RxJS比如`debounceTime`、`distinctUntilChanged`和`switchMap`操作符, 虽然它们的模板几乎相同,但是这个“智能”版涉及到了更多RxJS比如`debounceTime`、`distinctUntilChanged`和`switchMap`操作符,
就像[前面提过的那样](#rxjs-library)导入。 就像[前面提过的那样](#rxjs-library)导入。
a#create-stream a#create-stream

View File

@ -66,7 +66,7 @@ table(width="100%")
Initialized with an e2e test for the "Hello Angular" sample. Initialized with an e2e test for the "Hello Angular" sample.
初始化后,有个"Hello Angular" 的例子的端对端测试。 初始化后,有个“Hello Angular” 的例子的端对端测试。
tr tr
td <code>node_modules/</code> td <code>node_modules/</code>
@ -158,7 +158,7 @@ table(width="100%")
[_Deleting non-essential files_](setup.html#non-essential "Setup: Deleting non-essential files") section. [_Deleting non-essential files_](setup.html#non-essential "Setup: Deleting non-essential files") section.
*Do this only in the beginning to avoid accidentally deleting your own tests and git setup!* *Do this only in the beginning to avoid accidentally deleting your own tests and git setup!*
这个列表中的文件在清理时可以删除,它是原始的"快速起步"种子工程中的测试和git维护文件。 这个列表中的文件在清理时可以删除,它是原始的“快速起步”种子工程中的测试和git维护文件。
步骤参见可选的[删除非必要文件](setup.html#non-essential "Setup: Deleting non-essential files")部分。 步骤参见可选的[删除非必要文件](setup.html#non-essential "Setup: Deleting non-essential files")部分。
*只在最初做这件事以免不小心删除了你自己的测试文件和git配置* *只在最初做这件事以免不小心删除了你自己的测试文件和git配置*
tr tr

View File

@ -2507,7 +2507,7 @@ figure.image-display
which is bound to the `currentHero` of the parent component. which is bound to the `currentHero` of the parent component.
这组指令在要添加或移除*组件元素*时会非常有用。 这组指令在要添加或移除*组件元素*时会非常有用。
这个例子会在`hero-switch.components.ts`中定义的四个"感人英雄"组件之间选择。 这个例子会在`hero-switch.components.ts`中定义的四个“感人英雄”组件之间选择。
每个组件都有一个[输入属性](#inputs-outputs "Input property")`hero`,它绑定到父组件的`currentHero`上。 每个组件都有一个[输入属性](#inputs-outputs "Input property")`hero`,它绑定到父组件的`currentHero`上。
Switch directives work as well with native elements and web components too. Switch directives work as well with native elements and web components too.

View File

@ -1137,7 +1137,7 @@ a#compile-components
`TestBed.compileComponents`方法会异步编译这个测试模块中配置的所有组件。 `TestBed.compileComponents`方法会异步编译这个测试模块中配置的所有组件。
在这个例子中,`BannerComponent`是唯一要编译的组件。 在这个例子中,`BannerComponent`是唯一要编译的组件。
当`compileComponents`完成时外部组件和css文件会被"内联",而`TestBed.createComponent`会用同步的方式创建一个`BannerComponent`的新实例。 当`compileComponents`完成时外部组件和css文件会被“内联”,而`TestBed.createComponent`会用同步的方式创建一个`BannerComponent`的新实例。
.l-sub-section .l-sub-section
:marked :marked
@ -1229,7 +1229,7 @@ a#waiting-compile-components
as you can see in _this_ <live-example name="setup" plnkr="quickstart-specs" title="QuickStart seed spec" embedded-style></live-example>. as you can see in _this_ <live-example name="setup" plnkr="quickstart-specs" title="QuickStart seed spec" embedded-style></live-example>.
It too calls `compileComponents` although it doesn't have to because the `AppComponent`'s template is inline. It too calls `compileComponents` although it doesn't have to because the `AppComponent`'s template is inline.
["快速起步" 种子工程](setup.html)为其`AppComponent`提供了简单的测试,在<live-example name="setup" plnkr="quickstart-specs" title="QuickStart seed spec" embedded-style></live-example>中可以看到。 [“快速起步” 种子工程](setup.html)为其`AppComponent`提供了简单的测试,在<live-example name="setup" plnkr="quickstart-specs" title="QuickStart seed spec" embedded-style></live-example>中可以看到。
它也调用了`compileComponents`,不过它并不是必须这么做,因为`AppComponent`的模板是内联的。 它也调用了`compileComponents`,不过它并不是必须这么做,因为`AppComponent`的模板是内联的。
There's no harm in it and you might call `compileComponents` anyway There's no harm in it and you might call `compileComponents` anyway
@ -1859,8 +1859,8 @@ a#dashboard-standalone
The "click" event binding responds by calling `DashboardHeroComponent.click()`. The "click" event binding responds by calling `DashboardHeroComponent.click()`.
`heroEl`是个`DebugElement`,它代表了英雄所在的`<div>`。 `heroEl`是个`DebugElement`,它代表了英雄所在的`<div>`。
测试程序用"click"事件名字来调用`triggerEventHandler`。 测试程序用“click”事件名字来调用`triggerEventHandler`。
调用`DashboardHeroComponent.click()`时,"click"事件绑定作出响应。 调用`DashboardHeroComponent.click()`时,“click”事件绑定作出响应。
If the component behaves as expected, `click()` tells the component's `selected` property to emit the `hero` object, If the component behaves as expected, `click()` tells the component's `selected` property to emit the `hero` object,
the test detects that value through its subscription to `selected`, and the test should pass. the test detects that value through its subscription to `selected`, and the test should pass.
@ -1879,7 +1879,7 @@ a#trigger-event-handler
In this example, the test triggers a "click" event with a null event object. In this example, the test triggers a "click" event with a null event object.
本例中测试程序用null事件对象触发"click"事件。 本例中测试程序用null事件对象触发“click”事件。
+makeExample('testing/ts/src/app/dashboard/dashboard-hero.component.spec.ts', 'trigger-event-handler')(format='.') +makeExample('testing/ts/src/app/dashboard/dashboard-hero.component.spec.ts', 'trigger-event-handler')(format='.')
:marked :marked
@ -4099,7 +4099,7 @@ a#query-predicate
:marked :marked
Here's an example of `Renderer` tests from the <live-example plnkr="bag-specs">live "Specs Bag" sample</live-example>. Here's an example of `Renderer` tests from the <live-example plnkr="bag-specs">live "Specs Bag" sample</live-example>.
下面是<live-example plnkr="bag-specs">在线"Specs Bag"例子</live-example>中`Renderer`测试程序的例子 下面是<live-example plnkr="bag-specs">在线“Specs Bag”例子</live-example>中`Renderer`测试程序的例子
+makeExample('testing/ts/src/app/bag/bag.spec.ts', 'dom-attributes')(format=".") +makeExample('testing/ts/src/app/bag/bag.spec.ts', 'dom-attributes')(format=".")
@ -4216,7 +4216,7 @@ table(width="100%")
They're installed when you run `npm install`. They're installed when you run `npm install`.
这些范例测试是为在Jasmine和karma而写的。 这些范例测试是为在Jasmine和karma而写的。
那两条"捷径"设置会把适当的Jasmine和Karma包添加到`package.json`的`devDependencies`区。 那两条“捷径”设置会把适当的Jasmine和Karma包添加到`package.json`的`devDependencies`区。
当我们运行`npm install`时,它们就会被安装上。 当我们运行`npm install`时,它们就会被安装上。
a(href="#top").to-top Back to top a(href="#top").to-top Back to top

View File

@ -113,7 +113,7 @@ include ../_util-fns
Suppose the user enters the letters "abc", and then backspaces to remove them one by one. Suppose the user enters the letters "abc", and then backspaces to remove them one by one.
Here's what the UI displays: Here's what the UI displays:
假设用户输入字母"abc",然后用退格键一个一个删除它们。 假设用户输入字母“abc”,然后用退格键一个一个删除它们。
用户界面将显示: 用户界面将显示:
code-example(). code-example().
a | ab | abc | ab | a | | a | ab | abc | ab | a | |

View File

@ -52,7 +52,7 @@ code-example(language="sh" class="code-shell").
This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes. This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes.
The command simultaneously launches the app in a browser and refreshes the browser when the code changes. The command simultaneously launches the app in a browser and refreshes the browser when the code changes.
这个命令会在"监听"模式下运行TypeScript编译器当代码变化时它会自动重新编译。 这个命令会在“监听”模式下运行TypeScript编译器当代码变化时它会自动重新编译。
同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。 同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。
You can keep building the Tour of Heroes without pausing to recompile or refresh the browser. You can keep building the Tour of Heroes without pausing to recompile or refresh the browser.
@ -68,7 +68,7 @@ code-example(language="sh" class="code-shell").
Add two properties to the `AppComponent`: a `title` property for the app name and a `hero` property Add two properties to the `AppComponent`: a `title` property for the app name and a `hero` property
for a hero named "Windstorm." for a hero named "Windstorm."
往`AppComponent`中添加两个属性:`title`属性用来表示应用的名字,而`hero`属性用来表示名叫"Windstorm"的英雄。 往`AppComponent`中添加两个属性:`title`属性用来表示应用的名字,而`hero`属性用来表示名叫“Windstorm”的英雄。
+makeExample('toh-1/ts/app/app.component.1.ts', 'app-component-1', 'app.component.ts (AppComponent class)')(format=".") +makeExample('toh-1/ts/app/app.component.1.ts', 'app-component-1', 'app.component.ts (AppComponent class)')(format=".")
@ -198,7 +198,7 @@ code-example(language="sh" class="code-shell").
"`ngModel` ... isn't a known property of `input`." "`ngModel` ... isn't a known property of `input`."
不幸的是,做了这项改动之后,我们的程序崩溃了。 不幸的是,做了这项改动之后,我们的程序崩溃了。
打开浏览器的控制台我们会看到Angular抱怨说"`ngModel` ... isn't a known property of `input`."`ngModel`不是`input`元素的已知属性) 打开浏览器的控制台我们会看到Angular抱怨说“`ngModel` ... isn't a known property of `input`.”`ngModel`不是`input`元素的已知属性)
Although `NgModel` is a valid Angular directive, it isn't available by default. Although `NgModel` is a valid Angular directive, it isn't available by default.
It belongs to the optional `FormsModule`. It belongs to the optional `FormsModule`.

View File

@ -55,7 +55,7 @@ code-example(language="sh" class="code-shell").
This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes. This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes.
The command simultaneously launches the app in a browser and refreshes the browser when the code changes. The command simultaneously launches the app in a browser and refreshes the browser when the code changes.
这个命令会在"监听"模式下运行TypeScript编译器当代码变化时它会自动重新编译。 这个命令会在“监听”模式下运行TypeScript编译器当代码变化时它会自动重新编译。
同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。 同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。
You can keep building the Tour of Heroes without pausing to recompile or refresh the browser. You can keep building the Tour of Heroes without pausing to recompile or refresh the browser.
@ -394,7 +394,7 @@ code-example(language="sh" class="code-shell").
在我们前面添加的`styles`元数据中,有一个名叫`selected`的自定义CSS类。 在我们前面添加的`styles`元数据中,有一个名叫`selected`的自定义CSS类。
要想让选中的英雄更加醒目,当用户点击一个英雄名字时,我们要为`<li>`添加`selected`类。 要想让选中的英雄更加醒目,当用户点击一个英雄名字时,我们要为`<li>`添加`selected`类。
例如,当用户点击"Magneta"时,它应该使用不一样的醒目的背景色。 例如,当用户点击“Magneta”时,它应该使用不一样的醒目的背景色。
figure.image-display figure.image-display
img(src='/resources/images/devguide/toh/heroes-list-selected.png' alt="选中的英雄") img(src='/resources/images/devguide/toh/heroes-list-selected.png' alt="选中的英雄")

View File

@ -69,7 +69,7 @@ code-example(language="sh" class="code-shell").
This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes. This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes.
The command simultaneously launches the app in a browser and refreshes the browser when the code changes. The command simultaneously launches the app in a browser and refreshes the browser when the code changes.
这个命令会在"监听"模式下运行TypeScript编译器当代码变化时它会自动重新编译。 这个命令会在“监听”模式下运行TypeScript编译器当代码变化时它会自动重新编译。
同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。 同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。
You can keep building the Tour of Heroes without pausing to recompile or refresh the browser. You can keep building the Tour of Heroes without pausing to recompile or refresh the browser.

View File

@ -96,7 +96,7 @@ code-example(language="sh" class="code-shell").
This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes. This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes.
The command simultaneously launches the app in a browser and refreshes the browser when the code changes. The command simultaneously launches the app in a browser and refreshes the browser when the code changes.
这个命令会在"监听"模式下运行TypeScript编译器当代码变化时它会自动重新编译。 这个命令会在“监听”模式下运行TypeScript编译器当代码变化时它会自动重新编译。
同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。 同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。
:marked :marked
@ -774,7 +774,7 @@ code-example(format="nocode").
You don't need to add the hero clicks until the `HeroDetailComponent` You don't need to add the hero clicks until the `HeroDetailComponent`
is revised and ready to be navigated to. is revised and ready to be navigated to.
要想支持"点击英雄",就得先对`HeroDetailComponent`进行修改,好让我们能导航到它。 要想支持“点击英雄”,就得先对`HeroDetailComponent`进行修改,好让我们能导航到它。
.l-main-section .l-main-section
:marked :marked
@ -978,7 +978,7 @@ code-example(format="nocode").
destination routes, "/dashboard" and "/heroes". destination routes, "/dashboard" and "/heroes".
注意`[routerLink]`绑定。正如本章的[Router links](#router-links)部分所说, 注意`[routerLink]`绑定。正如本章的[Router links](#router-links)部分所说,
[`AppComponent`模板](#router-links)中的顶级导航有一些路由器链接被设置固定的路径,例如"/dashboard" and "/heroes" [`AppComponent`模板](#router-links)中的顶级导航有一些路由器链接被设置固定的路径,例如“/dashboard”和“/heroes”
This time, you're binding to an expression containing a *link parameters array*. This time, you're binding to an expression containing a *link parameters array*.
The array has two elements: the *path* of The array has two elements: the *path* of

View File

@ -54,7 +54,7 @@ code-example(language="sh" class="code-shell").
This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes. This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes.
The command simultaneously launches the app in a browser and refreshes the browser when the code changes. The command simultaneously launches the app in a browser and refreshes the browser when the code changes.
这个命令会在"监听"模式下运行TypeScript编译器当代码变化时它会自动重新编译。 这个命令会在“监听”模式下运行TypeScript编译器当代码变化时它会自动重新编译。
同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。 同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。
:marked :marked