翻译完了服务器通讯部分
This commit is contained in:
parent
22359a2496
commit
07fa6ecb15
|
@ -588,7 +588,7 @@ a#json
|
||||||
:marked
|
:marked
|
||||||
## Taking a look at the form model
|
## Taking a look at the form model
|
||||||
|
|
||||||
表单模型概览
|
## 表单模型概览
|
||||||
|
|
||||||
The value goes into the **_form model_** that backs the group's `FormControls`.
|
The value goes into the **_form model_** that backs the group's `FormControls`.
|
||||||
To see the form model, add the following line after the
|
To see the form model, add the following line after the
|
||||||
|
|
|
@ -25,6 +25,8 @@ block includes
|
||||||
|
|
||||||
The Angular HTTP library simplifies application programming with the **XHR** and **JSONP** APIs.
|
The Angular HTTP library simplifies application programming with the **XHR** and **JSONP** APIs.
|
||||||
|
|
||||||
|
Angular的HTTP库,简化了使用**XHR**和**JSONP** API的编程方式。
|
||||||
|
|
||||||
# Contents
|
# Contents
|
||||||
|
|
||||||
# 目录
|
# 目录
|
||||||
|
@ -41,12 +43,10 @@ block includes
|
||||||
|
|
||||||
[《英雄指南》的*HTTP*客户端演示程序](#http-client)
|
[《英雄指南》的*HTTP*客户端演示程序](#http-client)
|
||||||
|
|
||||||
|
|
||||||
* [The `HeroListComponent` class](#HeroListComponent)
|
* [The `HeroListComponent` class](#HeroListComponent)
|
||||||
|
|
||||||
[`HeroListComponent`类](#HeroListComponent)
|
[`HeroListComponent`类](#HeroListComponent)
|
||||||
|
|
||||||
|
|
||||||
* [Fetch data with `http.get()`](#fetch-data)
|
* [Fetch data with `http.get()`](#fetch-data)
|
||||||
|
|
||||||
[使用`http.get()`获取数据](#fetch-data)
|
[使用`http.get()`获取数据](#fetch-data)
|
||||||
|
@ -79,7 +79,6 @@ block includes
|
||||||
|
|
||||||
[`HeroListComponent`错误处理](#hero-list-component)
|
[`HeroListComponent`错误处理](#hero-list-component)
|
||||||
|
|
||||||
|
|
||||||
* [Send data to the server](#update)
|
* [Send data to the server](#update)
|
||||||
|
|
||||||
[把数据发到服务器](#update)
|
[把数据发到服务器](#update)
|
||||||
|
@ -92,7 +91,6 @@ block includes
|
||||||
|
|
||||||
[JSON结果](#json-results)
|
[JSON结果](#json-results)
|
||||||
|
|
||||||
|
|
||||||
* [Fall back to promises](#promises)
|
* [Fall back to promises](#promises)
|
||||||
|
|
||||||
[退化为承诺(Promise)](#promises)
|
[退化为承诺(Promise)](#promises)
|
||||||
|
@ -101,7 +99,6 @@ block includes
|
||||||
|
|
||||||
[跨域请求:Wikipedia范例](#cors)
|
[跨域请求:Wikipedia范例](#cors)
|
||||||
|
|
||||||
|
|
||||||
* [Search Wikipedia](#search-wikipedia)
|
* [Search Wikipedia](#search-wikipedia)
|
||||||
|
|
||||||
[搜索 Wikipedia](#search-wikipedia)
|
[搜索 Wikipedia](#search-wikipedia)
|
||||||
|
@ -130,7 +127,6 @@ block includes
|
||||||
|
|
||||||
[监听搜索词汇](#listen-for-search-terms)
|
[监听搜索词汇](#listen-for-search-terms)
|
||||||
|
|
||||||
|
|
||||||
* [Guarding against Cross-Site Request Forgery](#xsrf)
|
* [Guarding against Cross-Site Request Forgery](#xsrf)
|
||||||
|
|
||||||
[防范跨站请求(CSRF)攻击](#xsrf)
|
[防范跨站请求(CSRF)攻击](#xsrf)
|
||||||
|
@ -1100,16 +1096,27 @@ block wikipedia-jsonp+
|
||||||
there's a lot more RxJS in the "smart" version,
|
there's a lot more RxJS in the "smart" version,
|
||||||
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-library)导入。
|
||||||
|
|
||||||
a#create-stream
|
a#create-stream
|
||||||
:marked
|
:marked
|
||||||
### Create a stream of search terms
|
### Create a stream of search terms
|
||||||
|
|
||||||
|
### 创建一个搜索关键词的流
|
||||||
|
|
||||||
The `WikiComponent` passes a new search term directly to the `WikipediaService` after every keystroke.
|
The `WikiComponent` passes a new search term directly to the `WikipediaService` after every keystroke.
|
||||||
|
|
||||||
|
每当按键时,`WikiComponent`就会把一个新的搜索词直接传给`WikipediaService`。
|
||||||
|
|
||||||
The `WikiSmartComponent` class turns the user's keystrokes into an Observable _stream of search terms_
|
The `WikiSmartComponent` class turns the user's keystrokes into an Observable _stream of search terms_
|
||||||
with the help of a `Subject`, which you import from RxJS:
|
with the help of a `Subject`, which you import from RxJS:
|
||||||
|
|
||||||
|
`WikiSmartComponent`类借助一个`Subject`实例把用户的按键传给一个搜索关键词的可观察流(Observable stream)。`Subject`是从RxJS中导入的。
|
||||||
|
|
||||||
+makeExample('server-communication/ts/src/app/wiki/wiki-smart.component.ts', 'import-subject')(format='.')
|
+makeExample('server-communication/ts/src/app/wiki/wiki-smart.component.ts', 'import-subject')(format='.')
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
The component creates a `searchTermStream` as a `Subject` of type `string`.
|
The component creates a `searchTermStream` as a `Subject` of type `string`.
|
||||||
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.
|
||||||
|
@ -1122,28 +1129,50 @@ block wikipedia-jsonp+
|
||||||
a#listen-for-search-terms
|
a#listen-for-search-terms
|
||||||
:marked
|
:marked
|
||||||
### Listen for search terms
|
### Listen for search terms
|
||||||
|
|
||||||
|
### 监听搜索词
|
||||||
|
|
||||||
The `WikiSmartComponent` listens to the *stream of search terms* and
|
The `WikiSmartComponent` listens to the *stream of search terms* and
|
||||||
processes that stream _before_ calling the service.
|
processes that stream _before_ calling the service.
|
||||||
|
|
||||||
|
`WikiSmartComponent`监听*搜索关键词的流*,并且可以在调用搜索服务*之前*处理这个流。
|
||||||
|
|
||||||
+makeExample('server-communication/ts/src/app/wiki/wiki-smart.component.ts', 'observable-operators')(format='.')
|
+makeExample('server-communication/ts/src/app/wiki/wiki-smart.component.ts', 'observable-operators')(format='.')
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
* <a href="https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/debounce.md" target="_blank" title="debounce operator"><i>debounceTime</i></a>
|
* <a href="https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/debounce.md" target="_blank" title="debounce operator"><i>debounceTime</i></a>
|
||||||
waits for the user to stop typing for at least 300 milliseconds.
|
waits for the user to stop typing for at least 300 milliseconds.
|
||||||
|
|
||||||
|
<a href="https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/debounce.md" target="_blank" title="debounce operator"><i>debounceTime</i></a>
|
||||||
|
(防抖动)会等用户停止键入至少300毫秒后才触发。
|
||||||
|
|
||||||
* <a href="https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/distinctuntilchanged.md" target="_blank" title="distinctUntilChanged operator"><i>distinctUntilChanged</i></a>
|
* <a href="https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/distinctuntilchanged.md" target="_blank" title="distinctUntilChanged operator"><i>distinctUntilChanged</i></a>
|
||||||
ensures that the service is called only when the new search term is different from the previous search term.
|
ensures that the service is called only when the new search term is different from the previous search term.
|
||||||
|
|
||||||
|
<a href="https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/distinctuntilchanged.md" target="_blank" title="distinctUntilChanged operator"><i>distinctUntilChanged</i></a>
|
||||||
|
会确保只有在新的搜索关键词和以前的那个不同时才会调用搜索服务。
|
||||||
|
|
||||||
* The <a href="https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/flatmaplatest.md" target="_blank" title="switchMap operator"><i>switchMap</i></a>
|
* The <a href="https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/flatmaplatest.md" target="_blank" title="switchMap operator"><i>switchMap</i></a>
|
||||||
calls the `WikipediaService` with a fresh, debounced search term and coordinates the stream(s) of service response.
|
calls the `WikipediaService` with a fresh, debounced search term and coordinates the stream(s) of service response.
|
||||||
|
|
||||||
|
<a href="https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/flatmaplatest.md" target="_blank" title="switchMap operator"><i>switchMap</i></a>
|
||||||
|
会用一个新的、防抖过的搜索关键词来调用`WikipediaService`,并切换到该服务的响应流。
|
||||||
|
|
||||||
The role of `switchMap` is particularly important.
|
The role of `switchMap` is particularly important.
|
||||||
The `WikipediaService` returns a separate Observable of string arrays (`Observable<string[]>`) for each search request.
|
The `WikipediaService` returns a separate Observable of string arrays (`Observable<string[]>`) for each search request.
|
||||||
The user could issue multiple requests before a slow server has had time to reply,
|
The user could issue multiple requests before a slow server has had time to reply,
|
||||||
which means a backlog of response Observables could arrive at the client, at any moment, in any order.
|
which means a backlog of response Observables could arrive at the client, at any moment, in any order.
|
||||||
|
|
||||||
|
`switchMap`的角色是至关重要的。
|
||||||
|
`WikipediaService`为每个搜索请求返回一个独立的字符串数组型的可观察对象(`Observable<string[]>`)。
|
||||||
|
在一个慢速服务器有时间回复之前,用户可能会发起多个请求,这意味着这个流中的响应体可能在任何时刻、以任何顺序抵达客户端。
|
||||||
|
|
||||||
The `switchMap` returns its own Observable that _combines_ all `WikipediaService` response Observables,
|
The `switchMap` returns its own Observable that _combines_ all `WikipediaService` response Observables,
|
||||||
re-arranges them in their original request order,
|
re-arranges them in their original request order,
|
||||||
and delivers to subscribers only the most recent search results.
|
and delivers to subscribers only the most recent search results.
|
||||||
|
|
||||||
|
`switchMap`返回一个自有的可观察对象,该对象*组合*了`WikipediaService`中的所有响应体,
|
||||||
|
并把它们按原始请求顺序排列,只把最近一次返回的搜索结果提交给订阅者。
|
||||||
|
|
||||||
a#xsrf
|
a#xsrf
|
||||||
.l-main-section
|
.l-main-section
|
||||||
|
@ -1173,44 +1202,72 @@ a#xsrf
|
||||||
服务器接受这个 cookie 和页头,比较它们,只有在它们匹配的时候才处理请求。
|
服务器接受这个 cookie 和页头,比较它们,只有在它们匹配的时候才处理请求。
|
||||||
|
|
||||||
See the [XSRF topic on the Security page](security.html#xsrf) for more information about XSRF and Angular's `XSRFStrategy` counter measures.
|
See the [XSRF topic on the Security page](security.html#xsrf) for more information about XSRF and Angular's `XSRFStrategy` counter measures.
|
||||||
|
|
||||||
|
参见["安全"一章的XSRF主题](security.html#xsrf),以了解关于XSRF和Angular的应对措施`XSRFStrategy`的更多信息。
|
||||||
|
|
||||||
a#override-default-request-options
|
a#override-default-request-options
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
## Override default request headers (and other request options)
|
## Override default request headers (and other request options)
|
||||||
|
|
||||||
|
## 覆盖默认的请求头(及其它请求选项)
|
||||||
|
|
||||||
Request options (such as headers) are merged into the
|
Request options (such as headers) are merged into the
|
||||||
[default _RequestOptions_](https://angular.io/docs/ts/latest/api/http/index/BaseRequestOptions-class.html "API: BaseRequestOptions")
|
[default _RequestOptions_](https://angular.io/docs/ts/latest/api/http/index/BaseRequestOptions-class.html "API: BaseRequestOptions")
|
||||||
before the request is processed.
|
before the request is processed.
|
||||||
The `HttpModule` provides these default options via the `RequestOptions` token.
|
The `HttpModule` provides these default options via the `RequestOptions` token.
|
||||||
|
|
||||||
|
请求选项(比如请求头),会在发起请求之前并入[default _RequestOptions_](https://angular.io/docs/ts/latest/api/http/index/BaseRequestOptions-class.html "API: BaseRequestOptions")中。
|
||||||
|
`HttpModule`通过`RequestOptions`令牌提供了这些默认选项。
|
||||||
|
|
||||||
You can override these defaults to suit your application needs
|
You can override these defaults to suit your application needs
|
||||||
by creating a custom sub-class of `RequestOptions`
|
by creating a custom sub-class of `RequestOptions`
|
||||||
that sets the default options for the application.
|
that sets the default options for the application.
|
||||||
|
|
||||||
|
我们可以通过创建一个`RequestOptions`的子类来把这些默认值覆盖为本应用中的默认选项,以适应应用中的需求。
|
||||||
|
|
||||||
This sample creates a class that sets the default `Content-Type` header to JSON.
|
This sample creates a class that sets the default `Content-Type` header to JSON.
|
||||||
It exports a constant with the necessary `RequestOptions` provider to simplify registration in `AppModule`.
|
It exports a constant with the necessary `RequestOptions` provider to simplify registration in `AppModule`.
|
||||||
|
|
||||||
|
这个例子创建了一个类,它把默认的`Content-Type`请求头设置为JSON。
|
||||||
|
它导出了一个带有`RequestOptions`提供商的常量,以便注册进`AppModule`中。
|
||||||
|
|
||||||
+makeExample('server-communication/ts/src/app/default-request-options.service.ts', '', 'src/app/default-request-options.service.ts')(format=".")
|
+makeExample('server-communication/ts/src/app/default-request-options.service.ts', '', 'src/app/default-request-options.service.ts')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Then it registers the provider in the root `AppModule`.
|
Then it registers the provider in the root `AppModule`.
|
||||||
|
|
||||||
|
然后,它在根模块`AppModule`中注册了这个提供商。
|
||||||
|
|
||||||
+makeExample('server-communication/ts/src/app/app.module.ts', 'provide-default-request-options', 'src/app/app.module.ts (provide default request header)')(format=".")
|
+makeExample('server-communication/ts/src/app/app.module.ts', 'provide-default-request-options', 'src/app/app.module.ts (provide default request header)')(format=".")
|
||||||
|
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
Remember to include this provider during setup when unit testing the app's HTTP services.
|
Remember to include this provider during setup when unit testing the app's HTTP services.
|
||||||
|
|
||||||
|
在对应用的HTTP服务进行单元测试时,别忘了在初始化代码中包含这个提供商。
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
After this change, the `header` option setting in `HeroService.create()` is no longer necessary,
|
After this change, the `header` option setting in `HeroService.create()` is no longer necessary,
|
||||||
|
|
||||||
|
修改之后,`HeroService.create()`中的`header`选项就不再需要了。
|
||||||
|
|
||||||
+makeExcerpt('src/app/toh/hero.service.ts', 'create')
|
+makeExcerpt('src/app/toh/hero.service.ts', 'create')
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
You can confirm that `DefaultRequestOptions` is working by examing HTTP requests in the browser developer tools' network tab.
|
You can confirm that `DefaultRequestOptions` is working by examing HTTP requests in the browser developer tools' network tab.
|
||||||
If you're short-circuiting the server call with something like the [_in-memory web api_](#in-mem-web-api),
|
If you're short-circuiting the server call with something like the [_in-memory web api_](#in-mem-web-api),
|
||||||
try commenting-out the `create` header option,
|
try commenting-out the `create` header option,
|
||||||
set a breakpoint on the POST call, and step through the request processing
|
set a breakpoint on the POST call, and step through the request processing
|
||||||
to verify the header is there.
|
to verify the header is there.
|
||||||
|
|
||||||
|
打开浏览器开发者工具的network页,我们就可以确认,`DefaultRequestOptions`工作是否正常。
|
||||||
|
如果你通过某些机制(比如[内存Web API](#in-mem-web-api))短路了对服务器的调用,
|
||||||
|
可以试试注释掉`create`头选项,在POST调用上设置断点,并单步跟踪进请求过程来验证是否添加了这个头。
|
||||||
|
|
||||||
Individual requests options, like this one, take precedence over the default `RequestOptions`.
|
Individual requests options, like this one, take precedence over the default `RequestOptions`.
|
||||||
It might be wise to keep the `create` request header setting for extra safety.
|
It might be wise to keep the `create` request header setting for extra safety.
|
||||||
|
|
||||||
|
独立的请求选项,比如这一个,优先级高于默认的`RequestOptions`,保留`create`的请求头设置,以增强安全性,是一个明智之举。
|
||||||
|
|
||||||
a#in-mem-web-api
|
a#in-mem-web-api
|
||||||
.l-main-section
|
.l-main-section
|
||||||
|
@ -1258,14 +1315,15 @@ a#in-mem-web-api
|
||||||
It's an optional service in its own
|
It's an optional service in its own
|
||||||
<a href="https://github.com/angular/in-memory-web-api" target="_blank" title="In-memory Web API"><i>angular-in-memory-web-api</i></a>
|
<a href="https://github.com/angular/in-memory-web-api" target="_blank" title="In-memory Web API"><i>angular-in-memory-web-api</i></a>
|
||||||
library installed with npm (see `package.json`).
|
library installed with npm (see `package.json`).
|
||||||
|
|
||||||
|
内存Web API并不是Angular本身的一部分。
|
||||||
|
它是一个可选服务,要用npm来单独安装<a href="https://github.com/angular/in-memory-web-api" target="_blank" title="In-memory Web API"><i>angular-in-memory-web-api</i></a>库(参见`package.json`)。
|
||||||
|
|
||||||
See the
|
See the
|
||||||
<a href="https://github.com/angular/in-memory-web-api/blob/master/README.md" target="_blank" title='In-memory Web API "README.md"'><i>README file</i></a>
|
<a href="https://github.com/angular/in-memory-web-api/blob/master/README.md" target="_blank" title='In-memory Web API "README.md"'><i>README file</i></a>
|
||||||
for configuration options, default behaviors, and limitations.
|
for configuration options, default behaviors, and limitations.
|
||||||
|
|
||||||
内存 Web API 不是 Angular 内核的一部分。
|
参见<a href="https://github.com/angular/in-memory-web-api/blob/master/README.md" target="_blank" title='In-memory Web API "README.md"'><i>README file</i></a>来了解配置选项、默认行为和限制。
|
||||||
它是一个可选的服务,来自独立的`angular-in-memory-web-api`库。我们可以通过 npm (参见`package.json`) 来安装它,
|
|
||||||
并且通过 SystemJS (参见`systemjs.config.js`) 把它注册进模块加载器。
|
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
The in-memory web API gets its data from a custom application class with a `createDb()`
|
The in-memory web API gets its data from a custom application class with a `createDb()`
|
||||||
|
|
Loading…
Reference in New Issue