为方法加上括号

This commit is contained in:
Zhicheng Wang 2017-04-15 15:58:08 +08:00
parent f5c85b3e82
commit 26ba602922
17 changed files with 110 additions and 63 deletions

View File

@ -126,7 +126,7 @@ figure.image-display
Detect and act upon changes to input property values with the `ngOnChanges()` method of the `OnChanges` lifecycle hook interface. Detect and act upon changes to input property values with the `ngOnChanges()` method of the `OnChanges` lifecycle hook interface.
使用`OnChanges`生命周期钩子接口的`ngOnChanges`方法来监测输入属性值的变化并做出回应。 使用`OnChanges`生命周期钩子接口的`ngOnChanges()`方法来监测输入属性值的变化并做出回应。
.l-sub-section .l-sub-section
:marked :marked

View File

@ -706,7 +706,7 @@ a#committing-changes
The `onSubmit()` method simply replaces the `hero` object with the combined values of the form: The `onSubmit()` method simply replaces the `hero` object with the combined values of the form:
`onSubmit`方法直接使用表单的值得合集来替换`hero`对象: `onSubmit()`方法直接使用表单的值得合集来替换`hero`对象:
+makeExample('cb-form-validation/ts/src/app/reactive/hero-form-reactive.component.ts','on-submit')(format='.') +makeExample('cb-form-validation/ts/src/app/reactive/hero-form-reactive.component.ts','on-submit')(format='.')
.l-sub-section .l-sub-section
:marked :marked
@ -717,7 +717,7 @@ a#committing-changes
:marked :marked
The `addHero()` method discards pending changes and creates a brand new `hero` model object. The `addHero()` method discards pending changes and creates a brand new `hero` model object.
`addHero`方法放弃未处理的变化,并创建一个崭新的`hero`模型对象。 `addHero()`方法放弃未处理的变化,并创建一个崭新的`hero`模型对象。
+makeExample('cb-form-validation/ts/src/app/reactive/hero-form-reactive.component.ts','add-hero')(format='.') +makeExample('cb-form-validation/ts/src/app/reactive/hero-form-reactive.component.ts','add-hero')(format='.')
:marked :marked
Then it calls `buildForm()` again which replaces the previous `heroForm` control model with a new one. Then it calls `buildForm()` again which replaces the previous `heroForm` control model with a new one.

View File

@ -759,7 +759,7 @@ a#create-translation-providers
1. The `getTranslationsWithSystemJs()` method reads the translation and returns the contents as a string. 1. The `getTranslationsWithSystemJs()` method reads the translation and returns the contents as a string.
Notice that it appends `!text` to the filename, telling SystemJS to use the [text plugin](#text-plugin). Notice that it appends `!text` to the filename, telling SystemJS to use the [text plugin](#text-plugin).
`getTranslationsWithSystemJs`方法读取翻译并以字符串的形式返回其内容。 `getTranslationsWithSystemJs()`方法读取翻译并以字符串的形式返回其内容。
注意它在文件名上附加`!text`告诉SystemJS使用[文本插件](#text-plugin)。 注意它在文件名上附加`!text`告诉SystemJS使用[文本插件](#text-plugin)。
1. The callback composes a providers array with the three translation providers. 1. The callback composes a providers array with the three translation providers.
@ -779,7 +779,7 @@ a#bootstrap-the-app
The Angular `bootstrapModule()` method has a second _options_ parameter The Angular `bootstrapModule()` method has a second _options_ parameter
that can influence the behavior of the compiler. that can influence the behavior of the compiler.
Angular的`bootstrapModule`方法接受**可选的**第二参数,它可以影响编译器的行为。 Angular的`bootstrapModule()`方法接受**可选的**第二参数,它可以影响编译器的行为。
You'll create an _options_ object with the translation providers from `getTranslationProviders()` You'll create an _options_ object with the translation providers from `getTranslationProviders()`
and pass it to `bootstrapModule`. and pass it to `bootstrapModule`.

View File

@ -271,7 +271,7 @@ a#component
the root of filenames (such as `hero-list.component.ts`) are often the root of filenames (such as `hero-list.component.ts`) are often
spelled in dash-case. spelled in dash-case.
[指令](#directive)的选择器(例如`my-app`<span if-docs="ts">和文件名(例如`hero-list.component.ts`</span>通常是用中线命名法来命名。 [指令](#directive)的选择器(例如`my-app`)和文件名(例如`hero-list.component.ts`)通常是用中线命名法来命名。
:marked :marked
## Data binding ## Data binding
@ -301,7 +301,7 @@ a#component
Read about the following forms of binding in the [Template Syntax](./template-syntax.html) page: Read about the following forms of binding in the [Template Syntax](./template-syntax.html) page:
更多的绑定形式,见[模板语法](!{docsLatest}/guide/template-syntax.html#data-binding) 更多的绑定形式,见[模板语法](./template-syntax.html#data-binding)
* [Interpolation](./template-syntax.html#interpolation) * [Interpolation](./template-syntax.html#interpolation)
@ -619,12 +619,12 @@ a#H
Data values flow *into* this property from the data source identified Data values flow *into* this property from the data source identified
in the template expression to the right of the equal sign. in the template expression to the right of the equal sign.
输入属性是一个指令属性,可以作为[属性绑定 (property binding)](!{docsLatest}/guide/template-syntax.html#property-binding)的目标。 输入属性是一个指令属性,可以作为[属性绑定 (property binding)](./template-syntax.html#property-binding)的目标。
数据值会从模板表达式等号右侧的数据源流入这个属性。 数据值会从模板表达式等号右侧的数据源流入这个属性。
See the [Input and output properties](./template-syntax.html#inputs-outputs) section of the [Template Syntax](./template-syntax.html) page. See the [Input and output properties](./template-syntax.html#inputs-outputs) section of the [Template Syntax](./template-syntax.html) page.
见[模板语法](!{docsLatest}/guide/template-syntax.html)中的[输入与输出属性](!{docsLatest}/guide/template-syntax.html#inputs-outputs)。 见[模板语法](./template-syntax.html)中的[输入与输出属性](./template-syntax.html#inputs-outputs)。
:marked :marked
## Interpolation ## Interpolation
@ -649,7 +649,7 @@ a#H
Read more about [interpolation](./template-syntax.html#interpolation) in the Read more about [interpolation](./template-syntax.html#interpolation) in the
[Template Syntax](./template-syntax.html) page. [Template Syntax](./template-syntax.html) page.
更多信息,见[模板语法](!{docsLatest}/guide/template-syntax.html)中的[插值表达式](!{docsLatest}/guide/template-syntax.html#interpolation)。 更多信息,见[模板语法](./template-syntax.html)中的[插值表达式](./template-syntax.html#interpolation)。
.l-main-section#J .l-main-section#J
@ -760,7 +760,7 @@ a#jit
* [Angular modules](#angular-module). * [Angular modules](#angular-module).
For details and examples, see the [Angular Modules](./ngmodule.html) page. For details and examples, see the [Angular Modules](./ngmodule.html) page.
[Angular 模块](#angular-module),见[Angular 模块](!{docsLatest}/guide/ngmodule.html)。 [Angular 模块](#angular-module),见[Angular 模块](./ngmodule.html)。
* ES2015 modules, as described in this section. * ES2015 modules, as described in this section.
@ -899,7 +899,7 @@ a#N
You can also write your own custom pipes. You can also write your own custom pipes.
Read more in the page on [pipes](./pipes.html). Read more in the page on [pipes](./pipes.html).
更多信息,见[管道](!{docsLatest}/guide/pipes.html)。 更多信息,见[管道](./pipes.html)。
:marked :marked
## Provider ## Provider
@ -973,7 +973,7 @@ a#Q
The Angular component router is a richly featured mechanism for configuring and managing the entire view navigation process, including the creation and destruction The Angular component router is a richly featured mechanism for configuring and managing the entire view navigation process, including the creation and destruction
of views. of views.
Angular 的[组件路由器 (component router)](!{docsLatest}/guide/router.html)是一个特性丰富的机制,可以配置和管理整个导航过程,包括建立和销毁视图。 Angular 的组件路由器是一个特性丰富的机制,可以配置和管理整个导航过程,包括建立和销毁视图。
In most cases, components become attached to a router by means In most cases, components become attached to a router by means
of a `RouterConfig` that defines routes to views. of a `RouterConfig` that defines routes to views.
@ -992,7 +992,7 @@ a#Q
For more information, see the [Routing & Navigation](./router.html) page. For more information, see the [Routing & Navigation](./router.html) page.
更多信息,见[路由与导航](!{docsLatest}/guide/router.html)。 更多信息,见[路由与导航](./router.html)。
:marked :marked
## Router module ## Router module
@ -1007,7 +1007,7 @@ a#Q
For more information, see the [Routing & Navigation](./router.html) page. For more information, see the [Routing & Navigation](./router.html) page.
更多信息,见[路由与导航](!{docsLatest}/guide/router.html)。 更多信息,见[路由与导航](./router.html)。
:marked :marked
## Routing component ## Routing component
@ -1022,7 +1022,7 @@ a#Q
For more information, see the [Routing & Navigation](./router.html) page. For more information, see the [Routing & Navigation](./router.html) page.
更多信息,见[路由与导航](!{docsLatest}/guide/router.html)。 更多信息,见[路由与导航](./router.html)。
.l-main-section#S .l-main-section#S
@ -1116,7 +1116,7 @@ a#structural-directives
Read more in the [Structural Directives](./structural-directives.html) page. Read more in the [Structural Directives](./structural-directives.html) page.
更多信息,见[结构型指令](!{docsLatest}/guide/structural-directives.html)。 更多信息,见[结构型指令](./structural-directives.html)。
// #enddocregion n-s-2 // #enddocregion n-s-2
@ -1175,7 +1175,7 @@ a#structural-directives
Read about how to build template-driven forms Read about how to build template-driven forms
in the [Forms](./forms.html) page. in the [Forms](./forms.html) page.
更多信息,见[表单](!{docsLatest}/guide/forms.html)。 更多信息,见[表单](./forms.html)。
:marked :marked
## Template expression ## Template expression
@ -1206,7 +1206,9 @@ a#structural-directives
The process of transforming code written in one form of JavaScript The process of transforming code written in one form of JavaScript
(such as TypeScript) into another form of JavaScript (such as [ES5](#es5)). (such as TypeScript) into another form of JavaScript (such as [ES5](#es5)).
把一种形式的 JavaScript例如 TypeScript转换成另一种形式的 JavaScript例如 [ES5](#es5))的过程。:marked 把一种形式的 JavaScript例如 TypeScript转换成另一种形式的 JavaScript例如 [ES5](#es5))的过程。
:marked
## TypeScript ## TypeScript
.l-sub-section .l-sub-section

View File

@ -726,7 +726,7 @@ a#service-needs-service
You call that property within the `getHeroes()` method when anyone asks for heroes. You call that property within the `getHeroes()` method when anyone asks for heroes.
现在,这个构造函数要求注入一个`Logger`类的实例,并把它存到名为`logger`的私有属性中。 现在,这个构造函数要求注入一个`Logger`类的实例,并把它存到名为`logger`的私有属性中。
当别人请求英雄数据时,在`getHeroes`方法中调用这个属性的方法。 当别人请求英雄数据时,在`getHeroes()`方法中调用这个属性的方法。
a#injectable a#injectable
:marked :marked
@ -1415,7 +1415,7 @@ a#injection-token
You can call `get()` with a second parameter, which is the value to return if the service You can call `get()` with a second parameter, which is the value to return if the service
is not found. Angular can't find the service if it's not registered with this or any ancestor injector. is not found. Angular can't find the service if it's not registered with this or any ancestor injector.
`get`方法如果不能解析所请求的服务,会抛出异常。 `get()`方法如果不能解析所请求的服务,会抛出异常。
调用`get`时,还可以使用第二个参数,一旦获取的服务 (`ROUS`) 没有在当前或任何祖先注入器中注册过, 调用`get`时,还可以使用第二个参数,一旦获取的服务 (`ROUS`) 没有在当前或任何祖先注入器中注册过,
就把它作为返回值。 就把它作为返回值。
.l-sub-section .l-sub-section

View File

@ -107,7 +107,7 @@ figure.image-display
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.
如果我们只在顶级(通常是根模块`AppModule`),这三个注入器看起来将是“平面”的。 如果我们只在顶级(通常是根模块`AppModule`),这三个注入器看起来将是“平面”的。
所有的申请都会冒泡到根<span if-docs="ts"><code>NgModule</code></span>进行处理,也就是我们在`!{_bootstrapModule}`方法中配置的那个。 所有的申请都会冒泡到根<code>NgModule</code>进行处理,也就是我们在`bootstrapModule`方法中配置的那个。
.l-main-section .l-main-section
:marked :marked

View File

@ -49,7 +49,7 @@ table(width="100%")
A first taste of Angular<span if-docs="ts"> with zero installation. A first taste of Angular<span if-docs="ts"> with zero installation.
Run "Hello World" in an online code editor and start playing with live code</span>. Run "Hello World" in an online code editor and start playing with live code</span>.
<span if-docs="ts">零配置第一次尝试 Angular </span><span if-docs="ts">在在线代码编辑器中运行 “Hello World”并利用在线代码开始体验</span> 零配置第一次尝试 Angular 在在线代码编辑器中运行 “Hello World”并利用在线代码开始体验。
tr(style=top) tr(style=top)
td td

View File

@ -376,8 +376,9 @@ table(width="100%")
Implements an `ngDoCheck()` method with custom change detection. Implements an `ngDoCheck()` method with custom change detection.
See how often Angular calls this hook and watch it post changes to a log. See how often Angular calls this hook and watch it post changes to a log.
实现了一个`ngDoCheck`方法,通过它可以自定义变更检测逻辑。 实现了一个`ngDoCheck()`方法,通过它可以自定义变更检测逻辑。
这里将会看到Angular会用什么频度调用这个钩子监视它的变化并把这些变化输出成一条日志。 这里将会看到Angular会用什么频度调用这个钩子监视它的变化并把这些变化输出成一条日志。
tr(style='vertical-align:top') tr(style='vertical-align:top')
td <a href="#afterview">AfterView</a> td <a href="#afterview">AfterView</a>
td td
@ -548,11 +549,11 @@ figure.image-display
*Reset*按钮清除了这个`heroes`列表。 *Reset*按钮清除了这个`heroes`列表。
Angular从DOM中移除了所有英雄的div并且同时销毁了附加在这些div上的侦探指令。 Angular从DOM中移除了所有英雄的div并且同时销毁了附加在这些div上的侦探指令。
侦探的`ngOnDestroy`方法汇报了它自己的临终时刻。 侦探的`ngOnDestroy()`方法汇报了它自己的临终时刻。
The `ngOnInit()` and `ngOnDestroy()` methods have more vital roles to play in real applications. The `ngOnInit()` and `ngOnDestroy()` methods have more vital roles to play in real applications.
在真实的应用程序中,`ngOnInit`和`ngOnDestroy`方法扮演着更重要的角色。 在真实的应用程序中,`ngOnInit()`和`ngOnDestroy()`方法扮演着更重要的角色。
a#oninit a#oninit
:marked :marked
@ -612,14 +613,14 @@ a#oninit
Angular calls `ngOnChanges()` before `ngOnInit()` and many times after that. Angular calls `ngOnChanges()` before `ngOnInit()` and many times after that.
It only calls `ngOnInit()` once. It only calls `ngOnInit()` once.
我们访问这些属性的第一次机会,实际上是`ngOnChanges`方法Angular会在`ngOnInit`之前调用它。 我们访问这些属性的第一次机会,实际上是`ngOnChanges()`方法Angular会在`ngOnInit()`之前调用它。
但是在那之后Angular还会调用`ngOnChanges`很多次。而`ngOnInit`只会被调用一次。 但是在那之后Angular还会调用`ngOnChanges()`很多次。而`ngOnInit()`只会被调用一次。
:marked :marked
You can count on Angular to call the `ngOnInit()` method _soon_ after creating the component. You can count on Angular to call the `ngOnInit()` method _soon_ after creating the component.
That's where the heavy initialization logic belongs. That's where the heavy initialization logic belongs.
你可以信任Angular会在创建组件后立刻调用`ngOnInit`方法。 你可以信任Angular会在创建组件后立刻调用`ngOnInit()`方法。
这里是放置复杂初始化逻辑的好地方。 这里是放置复杂初始化逻辑的好地方。
a#ondestroy a#ondestroy
@ -651,7 +652,7 @@ a#onchanges
Angular calls its `ngOnChanges()` method whenever it detects changes to ***input properties*** of the component (or directive). Angular calls its `ngOnChanges()` method whenever it detects changes to ***input properties*** of the component (or directive).
在这个例子中,我们监听了`OnChanges`钩子。 在这个例子中,我们监听了`OnChanges`钩子。
一旦检测到该组件(或指令)的***输入属性***发生了变化Angular就会调用它的`ngOnChanges`方法。 一旦检测到该组件(或指令)的***输入属性***发生了变化Angular就会调用它的`ngOnChanges()`方法。
This example monitors the `OnChanges` hook. This example monitors the `OnChanges` hook.
@ -663,7 +664,7 @@ a#onchanges
[SimpleChange](../api/core/index/SimpleChange-class.html) object holding the current and previous property values. [SimpleChange](../api/core/index/SimpleChange-class.html) object holding the current and previous property values.
This hook iterates over the changed properties and logs them. This hook iterates over the changed properties and logs them.
`ngOnChanges`方法获取了一个对象,它把每个发生变化的属性名都映射到了一个[SimpleChange](../api/core/index/SimpleChange-class.html)对象, `ngOnChanges()`方法获取了一个对象,它把每个发生变化的属性名都映射到了一个[SimpleChange](../api/core/index/SimpleChange-class.html)对象,
该对象中有属性的当前值和前一个值。我们在这些发生了变化的属性上进行迭代,并记录它们。 该对象中有属性的当前值和前一个值。我们在这些发生了变化的属性上进行迭代,并记录它们。
The example component, `OnChangesComponent`, has two input properties: `hero` and `power`. The example component, `OnChangesComponent`, has two input properties: `hero` and `power`.
@ -801,14 +802,14 @@ a#wait-a-tick
The `doSomething()` method updates the screen when the hero name exceeds 10 characters. The `doSomething()` method updates the screen when the hero name exceeds 10 characters.
当英雄的名字超过10个字符时`doSomething`方法就会更新屏幕。 当英雄的名字超过10个字符时`doSomething()`方法就会更新屏幕。
+makeExample('lifecycle-hooks/ts/src/app/after-view.component.ts', 'do-something', 'AfterViewComponent (doSomething)')(format=".") +makeExample('lifecycle-hooks/ts/src/app/after-view.component.ts', 'do-something', 'AfterViewComponent (doSomething)')(format=".")
:marked :marked
Why does the `doSomething()` method wait a tick before updating `comment`? Why does the `doSomething()` method wait a tick before updating `comment`?
为什么在更新`comment`属性之前,`doSomething`方法要等上一拍(tick) 为什么在更新`comment`属性之前,`doSomething()`方法要等上一拍(tick)
Angular's unidirectional data flow rule forbids updates to the view *after* it has been composed. Angular's unidirectional data flow rule forbids updates to the view *after* it has been composed.
Both of these hooks fire _after_ the component's view has been composed. Both of these hooks fire _after_ the component's view has been composed.
@ -949,7 +950,7 @@ a#no-unidirectional-flow-worries
This component's `doSomething()` method update's the component's data-bound `comment` property immediately. This component's `doSomething()` method update's the component's data-bound `comment` property immediately.
There's no [need to wait](#wait-a-tick). There's no [need to wait](#wait-a-tick).
该组件的`doSomething`方法立即更新了组件被绑定的`comment`属性。 该组件的`doSomething()`方法立即更新了组件被绑定的`comment`属性。
它[不用等](#wait-a-tick)下一回合。 它[不用等](#wait-a-tick)下一回合。
Recall that Angular calls both *AfterContent* hooks before calling either of the *AfterView* hooks. Recall that Angular calls both *AfterContent* hooks before calling either of the *AfterView* hooks.

View File

@ -599,7 +599,7 @@ h3#async-pipe The impure #[i AsyncPipe]
我们确实得小心点。 我们确实得小心点。
这个管道只有当所请求的URL发生变化时才会向服务器发起请求。它会缓存服务器的响应。 这个管道只有当所请求的URL发生变化时才会向服务器发起请求。它会缓存服务器的响应。
代码如下,<span if-docs="ts">它使用[Angular http](server-communication.html)客户端来接收数据</span> 代码如下,它使用[Angular http](server-communication.html)客户端来接收数据
+makeExample('src/app/fetch-json.pipe.ts') +makeExample('src/app/fetch-json.pipe.ts')
:marked :marked

View File

@ -2764,10 +2764,6 @@ a#add-secondary-route
You are in effect saying, _when the user clicks this link, display the component associated with the `compose` route in the `popup` outlet_. You are in effect saying, _when the user clicks this link, display the component associated with the `compose` route in the `popup` outlet_.
要使用`Router`进行相对导航,可以使用`ActivatedRoute`来告诉路由器我们正在*RouterState*中的什么地方,*RouterState*是激活路由组成的树。
要做到这一点,我们可以为`router.navigate`方法中*链接参数数组*后的对象型参数指定**relativeTo**属性。
只要把这个`relativeTo`属性设置为我们的`ActivatedRoute`路由器就会把我们的导航信息和当前URL合并在一起。
.l-sub-section .l-sub-section
:marked :marked
This `outlets` object within an outer object was completely unnecessary This `outlets` object within an outer object was completely unnecessary
@ -3369,7 +3365,7 @@ a#CanDeactivate
wanted to use this guard for this component and needed to get wanted to use this guard for this component and needed to get
the component's properties or confirm whether the router should allow navigation away from it. the component's properties or confirm whether the router should allow navigation away from it.
另外,我们也可以为`CrisisDetailComponent`创建一个特定的`CanDeactivate`守卫。在需要访问外部信息时,`canDeactivate`方法为提供了组件、`ActivatedRoute`和`RouterStateSnapshot`的当前实例。如果只想为这个组件使用该守卫,并且需要使用该组件属性、或者需要路由器确认是否允许从该组件导航出去时,这个守卫就非常有用。 另外,我们也可以为`CrisisDetailComponent`创建一个特定的`CanDeactivate`守卫。在需要访问外部信息时,`canDeactivate()`方法为提供了组件、`ActivatedRoute`和`RouterStateSnapshot`的当前实例。如果只想为这个组件使用该守卫,并且需要使用该组件属性、或者需要路由器确认是否允许从该组件导航出去时,这个守卫就非常有用。
+makeExcerpt('src/app/can-deactivate-guard.service.1.ts (component-specific)', '') +makeExcerpt('src/app/can-deactivate-guard.service.1.ts (component-specific)', '')

View File

@ -442,7 +442,10 @@ code-example(language="typescript").
参见Dave Smith在<a href="https://www.youtube.com/watch?v=9inczw6qtpY" target="_blank" title="Cross Site Request Funkery Securing Your Angular Apps From Evil Doers">AngularConnect 2016关于XSRF的演讲</a>。 参见Dave Smith在<a href="https://www.youtube.com/watch?v=9inczw6qtpY" target="_blank" title="Cross Site Request Funkery Securing Your Angular Apps From Evil Doers">AngularConnect 2016关于XSRF的演讲</a>。
h3#xssi Cross-site script inclusion (XSSI)h3#xssi 跨站脚本包含(XSSI) h3#xssi Cross-site script inclusion (XSSI)
h3#xssi 跨站脚本包含(XSSI)
:marked :marked
Cross-site script inclusion, also known as JSON vulnerability, can allow an attacker's website to Cross-site script inclusion, also known as JSON vulnerability, can allow an attacker's website to
read data from a JSON API. The attack works on older browsers by overriding native JavaScript read data from a JSON API. The attack works on older browsers by overriding native JavaScript

View File

@ -432,7 +432,7 @@ a#HeroService
In fact, the `http.get` method returns an **Observable** of HTTP Responses (`Observable<Response>`) from the RxJS library In fact, the `http.get` method returns an **Observable** of HTTP Responses (`Observable<Response>`) from the RxJS library
and `map()` is one of the RxJS *operators*. and `map()` is one of the RxJS *operators*.
事实上,`http.get`方法返回了一个 HTTP Response 类型的**可观察对象** (`Observable<Response>`),这个对象来自 RxJS 库,而`map`是 RxJS 的*操作符*之一。 事实上,`http.get`方法返回了一个 HTTP Response 类型的**可观察对象** (`Observable<Response>`),这个对象来自 RxJS 库,而`map()`是 RxJS 的*操作符*之一。
a#rxjs-library a#rxjs-library
.l-main-section .l-main-section
@ -474,7 +474,7 @@ a#rxjs-library
The `getHeroes()` method needs the `map()` and `catch()` operators so it imports them like this. The `getHeroes()` method needs the `map()` and `catch()` operators so it imports them like this.
每个代码文件都需要把它需要的操作符从RxJS库中导入并添加进来。 每个代码文件都需要把它需要的操作符从RxJS库中导入并添加进来。
`getHeroes`方法需要一个`map`和一个`catch`操作符,那就像这样导入它: `getHeroes()`方法需要一个`map()`和一个`catch()`操作符,那就像这样导入它:
+makeExample('server-communication/ts/src/app/toh/hero.service.ts', 'rxjs-imports', 'src/app/app.component.ts (import rxjs)')(format=".") +makeExample('server-communication/ts/src/app/toh/hero.service.ts', 'rxjs-imports', 'src/app/app.component.ts (import rxjs)')(format=".")
@ -605,7 +605,7 @@ block error-handling
The `handleError` method transforms the error into a developer-friendly message, The `handleError` method transforms the error into a developer-friendly message,
logs it to the console, and returns the message in a new, failed Observable via `Observable.throw`. logs it to the console, and returns the message in a new, failed Observable via `Observable.throw`.
`catch`操作符将错误对象传递给`http`的`handleError`方法。 `catch()`操作符将错误对象传递给`http`的`handleError()`方法。
服务处理器 (`handleError`) 把响应对象记录到控制台中, 服务处理器 (`handleError`) 把响应对象记录到控制台中,
把错误转换成对用户友好的消息,并且通过`Observable.throw`来把这个消息放进一个新的、用于表示“失败”的可观察对象。 把错误转换成对用户友好的消息,并且通过`Observable.throw`来把这个消息放进一个新的、用于表示“失败”的可观察对象。
@ -710,7 +710,7 @@ a#headers
In the `return` statement, `options` is the *third* argument of the `post()` method, as shown above. In the `return` statement, `options` is the *third* argument of the `post()` method, as shown above.
在`return`声明中,`options`是传给`post`方法的*第三个*参数,就像前面见过的那样。 在`return`声明中,`options`是传给`post()`方法的*第三个*参数,就像前面见过的那样。
a#json-results a#json-results
:marked :marked
@ -799,7 +799,7 @@ h2#promises 倒退为承诺 (Promise)
The only obvious difference is that you call `then()` on the returned Promise instead of `subscribe`. The only obvious difference is that you call `then()` on the returned Promise instead of `subscribe`.
Both methods take the same functional arguments. Both methods take the same functional arguments.
唯一一个比较明显的不同点是我们调用这个返回的承诺的`then`方法,而不再是`subscribe`。 唯一一个比较明显的不同点是我们调用这个返回的承诺的`then()`方法,而不再是`subscribe`。
我们给了这两个方法完全相同的调用参数。 我们给了这两个方法完全相同的调用参数。
.l-sub-section .l-sub-section
:marked :marked
@ -809,14 +809,14 @@ h2#promises 倒退为承诺 (Promise)
The Promise-based `then()` returns another Promise. You can keep chaining more `then()` and `catch()` calls, getting a new promise each time. The Promise-based `then()` returns another Promise. You can keep chaining more `then()` and `catch()` calls, getting a new promise each time.
基于承诺的`then`返回了另一个承诺。我们可以链式调用多个`then`和`catch`方法,每次都返回一个新的承诺。 基于承诺的`then()`返回了另一个承诺。我们可以链式调用多个`then()`和`catch()`方法,每次都返回一个新的承诺。
The `subscribe()` method returns a `Subscription`. A `Subscription` is not another `Observable`. The `subscribe()` method returns a `Subscription`. A `Subscription` is not another `Observable`.
It's the end of the line for Observables. You can't call `map()` on it or call `subscribe()` again. It's the end of the line for Observables. You can't call `map()` on it or call `subscribe()` again.
The `Subscription` object has a different purpose, signified by its primary method, `unsubscribe`. The `Subscription` object has a different purpose, signified by its primary method, `unsubscribe`.
但`subscribe`方法返回一个`Subscription`对象。但`Subscription`不是另一个`Observable`。 但`subscribe()`方法返回一个`Subscription`对象。但`Subscription`不是另一个`Observable`。
它是可观察对象的末端。我们不能在它上面调用`map`函数或再次调用`subscribe`函数。 它是可观察对象的末端。我们不能在它上面调用`map()`函数或再次调用`subscribe()`函数。
`Subscription`对象的设计目的是不同的,这从它的主方法`unsubscribe`就能看出来。 `Subscription`对象的设计目的是不同的,这从它的主方法`unsubscribe`就能看出来。
To understand the implications and consequences of subscriptions, watch [Ben Lesh's talk on Observables](https://www.youtube.com/watch?v=3LKMwkuK0ZE) or his video course on [egghead.io](https://egghead.io/lessons/rxjs-rxjs-observables-vs-promises). To understand the implications and consequences of subscriptions, watch [Ben Lesh's talk on Observables](https://www.youtube.com/watch?v=3LKMwkuK0ZE) or his video course on [egghead.io](https://egghead.io/lessons/rxjs-rxjs-observables-vs-promises).
@ -1112,7 +1112,7 @@ block wikipedia-jsonp+
The `search()` method adds each new search box value to that stream via the subject's `next()` method. The `search()` method adds each new search box value to that stream via the subject's `next()` method.
组件创建`searchTermStream`为`string`类型的`Subject`。 组件创建`searchTermStream`为`string`类型的`Subject`。
`search`方法通过`subject`的`next`方法,将每个新搜索框的值添加到数据流中。 `search()`方法通过`subject`的`next()`方法,将每个新搜索框的值添加到数据流中。
+makeExample('server-communication/ts/src/app/wiki/wiki-smart.component.ts', 'subject')(format='.') +makeExample('server-communication/ts/src/app/wiki/wiki-smart.component.ts', 'subject')(format='.')
@ -1316,7 +1316,7 @@ block redirect-to-web-api
The `forRoot()` method name is a strong reminder that you should only call the `InMemoryWebApiModule` _once_, The `forRoot()` method name is a strong reminder that you should only call the `InMemoryWebApiModule` _once_,
while setting the metadata for the root `AppModule`. Don't call it again. while setting the metadata for the root `AppModule`. Don't call it again.
`forRoot`方法的名字告诉我们,应该只在设置根模块`AppModule`时调用`InMemoryWebApiModule`*一次*。不要再次调用它。 `forRoot()`方法的名字告诉我们,应该只在设置根模块`AppModule`时调用`InMemoryWebApiModule`*一次*。不要再次调用它。
:marked :marked
Here is the final, revised version of <code>src/app/app.module.ts</code>, demonstrating these steps. Here is the final, revised version of <code>src/app/app.module.ts</code>, demonstrating these steps.

View File

@ -154,6 +154,7 @@ a#html
我们首先看看数据绑定的第一种形式 —— 插值表达式,它展示了模板的 HTML 可以有多丰富。 我们首先看看数据绑定的第一种形式 —— 插值表达式,它展示了模板的 HTML 可以有多丰富。
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部
.l-hr .l-hr
a#interpolation a#interpolation
@ -220,6 +221,7 @@ a#interpolation
讲解属性绑定之前,先深入了解一下模板表达式和模板语句。 讲解属性绑定之前,先深入了解一下模板表达式和模板语句。
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部
.l-hr .l-hr
a#template-expressions a#template-expressions
@ -325,6 +327,7 @@ a#expression-context
members of the expression context. members of the expression context.
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部
a#no-side-effectsa#expression-guidelines a#no-side-effectsa#expression-guidelines
:marked :marked
@ -429,7 +432,6 @@ a#no-side-effectsa#expression-guidelines
如果幂等的表达式返回一个对象(包括`Date`或`Array`),连续调用它两次,也应该返回同一个对象的*引用*。 如果幂等的表达式返回一个对象(包括`Date`或`Array`),连续调用它两次,也应该返回同一个对象的*引用*。
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部 a(href="#toc") 回到顶部
.l-hr .l-hr
@ -554,6 +556,7 @@ a#template-statements
除插值表达式外,还有各种各样的数据绑定语法,是学习它们是时候了。 除插值表达式外,还有各种各样的数据绑定语法,是学习它们是时候了。
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部
.l-hr .l-hr
a#binding-syntax a#binding-syntax
@ -925,7 +928,6 @@ table(width="100%")
放开眼界,我们来看看每种绑定类型的具体情况。 放开眼界,我们来看看每种绑定类型的具体情况。
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部 a(href="#toc") 回到顶部
.l-hr .l-hr
@ -1643,6 +1645,7 @@ a#custom-event
+makeExample('template-syntax/ts/src/app/app.component.html', 'event-binding-propagation')(format=".") +makeExample('template-syntax/ts/src/app/app.component.html', 'event-binding-propagation')(format=".")
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部
.l-hr .l-hr
a#two-way a#two-way
@ -1741,6 +1744,7 @@ a#two-way
幸运的是Angular 以 [_NgModel_](#ngModel) 指令为桥梁,允许在表单元素上使用双向数据绑定。 幸运的是Angular 以 [_NgModel_](#ngModel) 指令为桥梁,允许在表单元素上使用双向数据绑定。
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部
.l-hr .l-hr
a#directives a#directives
@ -1870,6 +1874,7 @@ a#ngClass
你既可以在初始化时调用`setCurrentClassess()`,也可以在所依赖的属性变化时调用。 你既可以在初始化时调用`setCurrentClassess()`,也可以在所依赖的属性变化时调用。
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部
.l-hr .l-hr
a#ngStyle a#ngStyle
@ -1916,6 +1921,7 @@ a#ngStyle
你既可以在初始化时调用`setCurrentStyles()`,也可以在所依赖的属性变化时调用。 你既可以在初始化时调用`setCurrentStyles()`,也可以在所依赖的属性变化时调用。
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部
.l-hr .l-hr
a#ngModel a#ngModel
@ -2007,6 +2013,7 @@ figure.image-display
p p
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部
.l-hr .l-hr
a#structural-directives a#structural-directives
@ -2291,6 +2298,7 @@ figure.image-display
p p
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部
.l-hr .l-hr
a#ngSwitch a#ngSwitch
@ -2336,6 +2344,7 @@ figure.image-display
+makeExample('template-syntax/ts/src/app/app.component.html', 'NgSwitch-div')(format=".") +makeExample('template-syntax/ts/src/app/app.component.html', 'NgSwitch-div')(format=".")
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部
.l-hr .l-hr
a#template-reference-variable a#template-reference-variable
@ -2405,6 +2414,7 @@ a#ref-var
+makeExample('template-syntax/ts/src/app/app.component.html', 'ref-fax')(format=".") +makeExample('template-syntax/ts/src/app/app.component.html', 'ref-fax')(format=".")
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部
.l-hr .l-hr
a#inputs-outputs a#inputs-outputs
@ -2604,6 +2614,7 @@ h3#aliasing-io
+makeExample('template-syntax/ts/src/app/click.directive.ts', 'output-myClick2')(format=".") +makeExample('template-syntax/ts/src/app/click.directive.ts', 'output-myClick2')(format=".")
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部
.l-hr .l-hr
a#expression-operators a#expression-operators
@ -2674,6 +2685,7 @@ code-example(language="json").
"rate": 325 } "rate": 325 }
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部
.l-hr .l-hr
a#safe-navigation-operator a#safe-navigation-operator
@ -2785,6 +2797,7 @@ code-example(language="html").
在像`a?.b?.c?.d`这样的长属性路径中,它工作得很完美。 在像`a?.b?.c?.d`这样的长属性路径中,它工作得很完美。
a(href="#toc") back to top a(href="#toc") back to top
a(href="#toc") 回到顶部
.l-hr .l-hr
:marked :marked

View File

@ -591,8 +591,10 @@ a#component-fixture
The `title` property value is interpolated into the DOM within `<h1>` tags. The `title` property value is interpolated into the DOM within `<h1>` tags.
Use the fixture's `DebugElement` to `query` for the `<h1>` element by CSS selector. Use the fixture's `DebugElement` to `query` for the `<h1>` element by CSS selector.
`title`属性被插值到DOM的`<h1>`标签中。 `title`属性被插值到DOM的`<h1>`标签中。
用CSS选择器从fixture的`DebugElement`中`query``<h1>`元素。 用CSS选择器从fixture的`DebugElement`中`query``<h1>`元素。
The **`query`** method takes a predicate function and searches the fixture's entire DOM tree for the The **`query`** method takes a predicate function and searches the fixture's entire DOM tree for the
_first_ element that satisfies the predicate. _first_ element that satisfies the predicate.
The result is a _different_ `DebugElement`, one associated with the matching DOM element. The result is a _different_ `DebugElement`, one associated with the matching DOM element.
@ -601,7 +603,9 @@ a#component-fixture
.l-sub-section .l-sub-section
:marked :marked
The `queryAll` method returns an array of _all_ `DebugElements` that satisfy the predicate. The `queryAll` method returns an array of _all_ `DebugElements` that satisfy the predicate.
`queryAll`方法返回一列数组,包含所有`DebugElement`中满足predicate的元素。 `queryAll`方法返回一列数组,包含所有`DebugElement`中满足predicate的元素。
A _predicate_ is a function that returns a boolean. A _predicate_ is a function that returns a boolean.
A query predicate receives a `DebugElement` and returns `true` if the element meets the selection criteria. A query predicate receives a `DebugElement` and returns `true` if the element meets the selection criteria.
**predicate**是返回布尔值的函数。 **predicate**是返回布尔值的函数。
@ -1000,9 +1004,11 @@ a#welcome-spec-setup
The second parameter to the Jasmine `it` (e.g., `'expected name'`) is an optional addendum. The second parameter to the Jasmine `it` (e.g., `'expected name'`) is an optional addendum.
If the expectation fails, Jasmine displays this addendum after the expectation failure message. If the expectation fails, Jasmine displays this addendum after the expectation failure message.
In a spec with multiple expectations, it can help clarify what went wrong and which expectation failed . In a spec with multiple expectations, it can help clarify what went wrong and which expectation failed .
Jasmine的`it`方法的第二个参数(比如`'expected name'`)是可选附加参数。
Jasmine的`it`方法的第二个参数(比如`'expected name'`)是可选附加参数。
如果这个期待失败了Jasmine在期待失败信息后面显示这个附加参数。 如果这个期待失败了Jasmine在期待失败信息后面显示这个附加参数。
在拥有多个期待的spec中它可以帮助澄清发生了什么错误哪个期待失败了。 在拥有多个期待的spec中它可以帮助澄清发生了什么错误哪个期待失败了。
:marked :marked
The remaining tests confirm the logic of the component when the service returns different values. The remaining tests confirm the logic of the component when the service returns different values.
The second test validates the effect of changing the user name. The second test validates the effect of changing the user name.
@ -1144,6 +1150,7 @@ a#when-stable
### _whenStable_ ### _whenStable_
## **whenStable** ## **whenStable**
The test must wait for the `getQuote` promise to resolve in the next turn of the JavaScript engine. The test must wait for the `getQuote` promise to resolve in the next turn of the JavaScript engine.
测试程序必须等待`getQuote`在JavaScript引擎的下一回合中被解析。 测试程序必须等待`getQuote`在JavaScript引擎的下一回合中被解析。
@ -1153,9 +1160,13 @@ a#when-stable
probes only the component API surface. probes only the component API surface.
本测试对`twainService.getQuote`返回的承诺没有直接的访问,因为它被埋没在`TwainComponent.ngOnInit`里, 本测试对`twainService.getQuote`返回的承诺没有直接的访问,因为它被埋没在`TwainComponent.ngOnInit`里,
所以对于只测试组件API表面的测试来说它是无法被访问的。Fortunately, the `getQuote` promise is accessible to the _async test zone_ , 所以对于只测试组件API表面的测试来说它是无法被访问的。
Fortunately, the `getQuote` promise is accessible to the _async test zone_ ,
which intercepts all promises issued within the _async_ method call _no matter where they occur_. which intercepts all promises issued within the _async_ method call _no matter where they occur_.
幸运的是,**异步测试区域**可以访问`getQuote`承诺,因为它拦截所有调用**异步**方法所发出的承诺,不管它们在哪儿。 幸运的是,**异步测试区域**可以访问`getQuote`承诺,因为它拦截所有调用**异步**方法所发出的承诺,不管它们在哪儿。
The `ComponentFixture.whenStable` method returns its own promise, which resolves when the `getQuote` promise finishes. The `ComponentFixture.whenStable` method returns its own promise, which resolves when the `getQuote` promise finishes.
In fact, the _whenStable_ promise resolves when _all pending asynchronous activities within this test_ complete &mdash; the definition of "stable." In fact, the _whenStable_ promise resolves when _all pending asynchronous activities within this test_ complete &mdash; the definition of "stable."
@ -1728,22 +1739,28 @@ a#routed-component-w-param
`HeroDetailComponent` subscribes to `ActivatedRoute.params` changes in its `ngOnInit` method. `HeroDetailComponent` subscribes to `ActivatedRoute.params` changes in its `ngOnInit` method.
`HeroDetailComponent`在它的`ngOnInit`方法中监听`ActivatedRoute.params`的变化。 `HeroDetailComponent`在它的`ngOnInit`方法中监听`ActivatedRoute.params`的变化。
+makeExample('testing/ts/src/app/hero/hero-detail.component.ts', 'ng-on-init', 'src/app/hero/hero-detail.component.ts (ngOnInit)')(format='.') +makeExample('testing/ts/src/app/hero/hero-detail.component.ts', 'ng-on-init', 'src/app/hero/hero-detail.component.ts (ngOnInit)')(format='.')
.l-sub-section .l-sub-section
:marked :marked
The expression after `route.params` chains an _Observable_ operator that _plucks_ the `id` from the `params` The expression after `route.params` chains an _Observable_ operator that _plucks_ the `id` from the `params`
and then chains a `forEach` operator to subscribe to `id`-changing events. and then chains a `forEach` operator to subscribe to `id`-changing events.
The `id` changes every time the user navigates to a different hero. The `id` changes every time the user navigates to a different hero.
`route.params`之后的表达式链接了**可观察**操作符,它从`params`中提取`id`,然后链接`forEach`操作符来订阅`id`变化事件。 `route.params`之后的表达式链接了**可观察**操作符,它从`params`中提取`id`,然后链接`forEach`操作符来订阅`id`变化事件。
每次`id`变化时,用户被导航到不同的英雄。 每次`id`变化时,用户被导航到不同的英雄。
The `forEach` passes the new `id` value to the component's `getHero` method (not shown) The `forEach` passes the new `id` value to the component's `getHero` method (not shown)
which fetches a hero and sets the component's `hero` property. which fetches a hero and sets the component's `hero` property.
If the`id` parameter is missing, the `pluck` operator fails and the `catch` treats failure as a request to edit a new hero. If the`id` parameter is missing, the `pluck` operator fails and the `catch` treats failure as a request to edit a new hero.
`forEach`将新的`id`值传递到组件的`getHero`方法(这里没有列出来),它获取英雄并将它赋值到组件的`hero`属性。 `forEach`将新的`id`值传递到组件的`getHero`方法(这里没有列出来),它获取英雄并将它赋值到组件的`hero`属性。
如果`id`参数无效,`pluck`操作符就会失败,`catch`将失败当作创建新英雄来处理。 如果`id`参数无效,`pluck`操作符就会失败,`catch`将失败当作创建新英雄来处理。
The [Router](router.html#route-parameters) guide covers `ActivatedRoute.params` in more detail. The [Router](router.html#route-parameters) guide covers `ActivatedRoute.params` in more detail.
[路由器](router.html#route-parameters)章更详尽的讲述了`ActivatedRoute.params`。 [路由器](router.html#route-parameters)章更详尽的讲述了`ActivatedRoute.params`。
:marked :marked
A test can explore how the `HeroDetailComponent` responds to different `id` parameter values A test can explore how the `HeroDetailComponent` responds to different `id` parameter values
by manipulating the `ActivatedRoute` injected into the component's constructor. by manipulating the `ActivatedRoute` injected into the component's constructor.
@ -1767,10 +1784,12 @@ a#stub-observable
This is a cross-application, re-usable _test helper class_. This is a cross-application, re-usable _test helper class_.
Consider placing such helpers in a `testing` folder sibling to the `app` folder. Consider placing such helpers in a `testing` folder sibling to the `app` folder.
This sample keeps `ActivatedRouteStub` in `testing/router-stubs.ts`: This sample keeps `ActivatedRouteStub` in `testing/router-stubs.ts`:
`hero-detail.component.spec.ts`依赖`ActivatedRouteStub`来为每个测试程序设置`ActivatedRoute.params`值。 `hero-detail.component.spec.ts`依赖`ActivatedRouteStub`来为每个测试程序设置`ActivatedRoute.params`值。
它是跨应用、可复用的**测试辅助类**。 它是跨应用、可复用的**测试辅助类**。
我们建议将这样的辅助类放到`app`目录下的名为`testing`的目录。 我们建议将这样的辅助类放到`app`目录下的名为`testing`的目录。
本例把`ActivatedRouteStub`放到`testing/router-stubs.ts` 本例把`ActivatedRouteStub`放到`testing/router-stubs.ts`
+makeExample('testing/ts/src/testing/router-stubs.ts', 'activated-route-stub', 'testing/router-stubs.ts (ActivatedRouteStub)')(format='.') +makeExample('testing/ts/src/testing/router-stubs.ts', 'activated-route-stub', 'testing/router-stubs.ts (ActivatedRouteStub)')(format='.')
:marked :marked
Notable features of this stub are: Notable features of this stub are:
@ -1922,6 +1941,7 @@ figure.image-display
A `createComponent` method creates a `page` objectand fills in the blanks once the `hero` arrives. A `createComponent` method creates a `page` objectand fills in the blanks once the `hero` arrives.
`createComponent`方法创建`page`,在`hero`到来时,自动填补空白。 `createComponent`方法创建`page`,在`hero`到来时,自动填补空白。
+makeExample('testing/ts/src/app/hero/hero-detail.component.spec.ts', 'create-component', 'src/app/hero/hero-detail.component.spec.ts (createComponent)')(format='.') +makeExample('testing/ts/src/app/hero/hero-detail.component.spec.ts', 'create-component', 'src/app/hero/hero-detail.component.spec.ts (createComponent)')(format='.')
:marked :marked
@ -2126,6 +2146,7 @@ a#override-component-method
Focus on the `overrideComponent` method. Focus on the `overrideComponent` method.
注意这个`overrideComponent`方法。 注意这个`overrideComponent`方法。
+makeExample('testing/ts/src/app/hero/hero-detail.component.spec.ts', 'override-component-method', 'src/app/hero/hero-detail.component.spec.ts (overrideComponent)')(format='.') +makeExample('testing/ts/src/app/hero/hero-detail.component.spec.ts', 'override-component-method', 'src/app/hero/hero-detail.component.spec.ts (overrideComponent)')(format='.')
:marked :marked
It takes two arguments: the component type to override (`HeroDetailComponent`) and an override metadata object. It takes two arguments: the component type to override (`HeroDetailComponent`) and an override metadata object.
@ -2197,8 +2218,10 @@ a#more-overrides
The `TestBed.overrideComponent` method can be called multiple times for the same or different components. The `TestBed.overrideComponent` method can be called multiple times for the same or different components.
The `TestBed` offers similar `overrideDirective`, `overrideModule`, and `overridePipe` methods The `TestBed` offers similar `overrideDirective`, `overrideModule`, and `overridePipe` methods
for digging into and replacing parts of these other classes. for digging into and replacing parts of these other classes.
`TestBed.overrideComponent`方法可以在相同或不同的组件中被反复调用。 `TestBed.overrideComponent`方法可以在相同或不同的组件中被反复调用。
`TestBed`还提供了类似的`overrideDirective`、`overrideModule`和`overridePipe`方法,用来深入并重载这些其它类的部件。 `TestBed`还提供了类似的`overrideDirective`、`overrideModule`和`overridePipe`方法,用来深入并重载这些其它类的部件。
Explore the options and combinations on your own. Explore the options and combinations on your own.
自己探索这些选项和组合。 自己探索这些选项和组合。
@ -3087,6 +3110,7 @@ table
(`null` in this example): (`null` in this example):
`TestBed.get`方法接受一个可选的第二参数它是在Angular找不到所需提供商时返回的对象。在本例中为`null` `TestBed.get`方法接受一个可选的第二参数它是在Angular找不到所需提供商时返回的对象。在本例中为`null`
+makeExample('testing/ts/src/app/bag/bag.spec.ts', 'testbed-get')(format=".") +makeExample('testing/ts/src/app/bag/bag.spec.ts', 'testbed-get')(format=".")
:marked :marked
After calling `get`, the `TestBed` configuration is frozen for the duration of the current spec. After calling `get`, the `TestBed` configuration is frozen for the duration of the current spec.
@ -3513,9 +3537,13 @@ a#query-predicate
:marked :marked
Many custom application directives inject the `Renderer` and call one of its `set...` methods. Many custom application directives inject the `Renderer` and call one of its `set...` methods.
很多制定应用程序指令注入`Renderer`并调用它其中一个方法`set...`。The test environment substitutes the `DebugDomRender` for the runtime `Renderer`. 很多制定应用程序指令注入`Renderer`并调用它其中一个方法`set...`。
The test environment substitutes the `DebugDomRender` for the runtime `Renderer`.
The `DebugDomRender` updates additional dictionary properties of the `DebugElement` The `DebugDomRender` updates additional dictionary properties of the `DebugElement`
when something calls a `set...` method.运行时的`Renderer`在测试环境中的替代品为`DebugDomRender`。 when something calls a `set...` method.
运行时的`Renderer`在测试环境中的替代品为`DebugDomRender`。
在调用`set...`方法时,`DebugDomRender`更新`DebugElement`额外词典属性。 在调用`set...`方法时,`DebugDomRender`更新`DebugElement`额外词典属性。
These dictionary properties are primarily of interest to authors of Angular DOM inspection tools These dictionary properties are primarily of interest to authors of Angular DOM inspection tools

View File

@ -24,7 +24,7 @@ block qs-src-online-and-local
Every component begins with an `@Component` [decorator](glossary.html#decorator '"decorator" explained') Every component begins with an `@Component` [decorator](glossary.html#decorator '"decorator" explained')
function that takes a _metadata_ object. The metadata object describes how the HTML template and component class work together. function that takes a _metadata_ object. The metadata object describes how the HTML template and component class work together.
每个组件都以`@Component`[装饰器](glossary.html#!{_decorator} '"!{_decorator}" explained')<span if-docs="ts">函数</span>开始,它<span if-docs="ts">接受一个_元数据_对象参数。该元素对象</span>描述了 HTML 模板和组件类是如何一起工作的。 每个组件都以`@Component`[装饰器](glossary.html#!{_decorator} '"!{_decorator}" explained')函数开始它接受一个_元数据_对象参数。该元素对象描述了 HTML 模板和组件类是如何一起工作的。
The `selector` property tells Angular to display the component inside a custom `<my-app>` tag in the `index.html`. The `selector` property tells Angular to display the component inside a custom `<my-app>` tag in the `index.html`.

View File

@ -203,9 +203,10 @@ code-example(language="sh" class="code-shell").
* Create the file <code>src/app/app.component.ts</code>. * Create the file <code>src/app/app.component.ts</code>.
创建一个名叫<span ngio-ex>src/app/app.component.ts</span>的新文件。 创建一个名叫<span ngio-ex>src/app/app.component.ts</span>的新文件。
* Define an exported `AppComponent` class. * Define an exported `AppComponent` class.
定义一个<span if-docs="ts">导出的</span> `AppComponent`类。 定义一个导出的 `AppComponent`类。
* Add an `@Component` decorator above the class with a `my-app` selector. * Add an `@Component` decorator above the class with a `my-app` selector.
@ -642,7 +643,7 @@ a#configure-routes
In this dashboard you specify four heroes (2nd, 3rd, 4th, and 5th) with the `Array.slice` method. In this dashboard you specify four heroes (2nd, 3rd, 4th, and 5th) with the `Array.slice` method.
在仪表盘中我们<span if-docs="ts">用`Array.slice`方法</span>提取了四个英雄第2、3、4、5个 在仪表盘中我们用`Array.slice`方法提取了四个英雄第2、3、4、5个
Refresh the browser to see four hero names in the new dashboard. Refresh the browser to see four hero names in the new dashboard.
@ -1305,7 +1306,7 @@ figure.image-display
在`!{_appDir}`目录下添加<span ngio-ex>hero-detail.component.css</span>文件, 在`!{_appDir}`目录下添加<span ngio-ex>hero-detail.component.css</span>文件,
并且在`styleUrls`数组中引用它 —— 就像之前在`DashboardComponent`中做过的那样。 并且在`styleUrls`数组中引用它 —— 就像之前在`DashboardComponent`中做过的那样。
同时删除`hero``@Input`装饰器属性<span if-docs="ts">和它的导入语句</span> 同时删除`hero``@Input`装饰器属性和它的导入语句。
Here's the content for the component CSS files. Here's the content for the component CSS files.

View File

@ -730,6 +730,8 @@ a#ngoninit
Even with a 300ms pause between requests, you could have multiple HTTP requests in flight Even with a 300ms pause between requests, you could have multiple HTTP requests in flight
and they may not return in the order sent. and they may not return in the order sent.
借助[switchMap操作符](http://www.learnrxjs.io/operators/transformation/switchmap.html)
(正式名称是`flatMapLatest`)
每次符合条件的按键事件都会触发一次对`http`方法的调用。即使在发送每个请求前都有 300 毫秒的延迟, 每次符合条件的按键事件都会触发一次对`http`方法的调用。即使在发送每个请求前都有 300 毫秒的延迟,
我们仍然可能同时拥有多个在途的 HTTP 请求,并且它们返回的顺序未必就是发送时的顺序。 我们仍然可能同时拥有多个在途的 HTTP 请求,并且它们返回的顺序未必就是发送时的顺序。
@ -737,8 +739,8 @@ a#ngoninit
only the observable from the most recent `http` method call. only the observable from the most recent `http` method call.
Results from prior calls are canceled and discarded. Results from prior calls are canceled and discarded.
`switchMap`保留了原始的请求顺序,并且只返回最近一次 `http` 调用返回的可观察对象。 `switchMap()`保留了原始的请求顺序,并且只返回最近一次 `http` 调用返回的可观察对象。
这是因为以前的调用都被取消或丢弃了。 这是因为以前的调用都被取消或丢弃了。
If the search text is empty, the `http()` method call is also short circuited If the search text is empty, the `http()` method call is also short circuited
and an observable containing an empty array is returned. and an observable containing an empty array is returned.
@ -752,6 +754,7 @@ a#ngoninit
注意_取消_`HeroSearchService`的可观察对象并不会实际中止 (abort) 一个未完成的 HTTP 请求, 注意_取消_`HeroSearchService`的可观察对象并不会实际中止 (abort) 一个未完成的 HTTP 请求,
除非服务支持这个特性,这个问题我们以后再讨论。 除非服务支持这个特性,这个问题我们以后再讨论。
目前我们的做法只是丢弃不希望的结果。 目前我们的做法只是丢弃不希望的结果。
:marked :marked
* `catch` intercepts a failed observable. * `catch` intercepts a failed observable.
The simple example prints the error to the console; a real life app would do better. The simple example prints the error to the console; a real life app would do better.