fix: sync to 6.0(WIP)

This commit is contained in:
Zhicheng Wang 2018-05-15 13:32:40 +08:00
parent 4ff1a42339
commit 2867ceecdb
15 changed files with 402 additions and 479 deletions

View File

@ -44,19 +44,19 @@ if they are not already on your machine.
<div class="l-sub-section">
**Verify that you are running at least node `6.9.x` and npm `3.x.x`**
**Verify that you are running at least Node.js version `8.x` or greater and npm version `5.x` or greater**
by running `node -v` and `npm -v` in a terminal/console window.
Older versions produce errors, but newer versions are fine.
请先在终端/控制台窗口中运行命令 `node -v``npm -v`
**来验证一下你正在运行 node `6.9.x` 和 npm `3.x.x` 以上的版本。**
**来验证一下你正在运行 node `8.x` 和 npm `5.x` 以上的版本。**
更老的版本可能会出现错误,更新的版本则没问题。
</div>
Then **install the [Angular CLI](https://github.com/angular/angular-cli)** globally.
Then install the [Angular CLI](https://github.com/angular/angular-cli) globally.
然后全局安装 **[Angular CLI](https://github.com/angular/angular-cli)**
然后全局安装 [Angular CLI](https://github.com/angular/angular-cli)。
<code-example language="sh" class="code-shell">
npm install -g @angular/cli
@ -71,22 +71,32 @@ Open a terminal window.
打开终端窗口。
Generate a new project and skeleton application by running the following commands:
Generate a new project and default app by running the following command:
运行下列命令来生成一个新项目以及应用的骨架代码:
运行下列命令来生成一个新项目以及默认的应用代码:
<code-example language="sh" class="code-shell">
ng new my-app
</code-example>
The Angular CLI installs the necessary npm packages, creates the project files, and populates the project with a simple default app. This can take some time.
Angular CLI 会安装必要的 NPM 包、创建项目文件,并在该项目中生成一个简单的默认应用。这可能要花一点时间。
<div class="l-sub-section">
Patience, please.
It takes time to set up a new project; most of it is spent installing npm packages.
You can add pre-packaged functionality to a new project by using the `ng add` command. The `ng add` command transforms a project by applying the schematics in the specified package.
For more information, see the [Angular CLI documentation.](https://github.com/angular/angular-cli/wiki/add "Angular CLI documentation")
请耐心等待。
创建新项目需要花费很多时间,大多数时候都是在安装那些 npm 包。
你可以使用 `ng add` 命令往新项目中添加一些预先打包好的功能。
`ng add` 命令会通过应用来自特定 NPM 包中的图纸schematic来转换此项目。
要了解更多,参见 [Angular CLI 文档](https://github.com/angular/angular-cli/wiki/add "Angular CLI documentation")。
Angular Material provides schematics for typical app layouts.
See the [Angular Material documentation](https://material.angular.io/guides "Angular Material documentation") for details.
比如 Angular Material 就为一些典型布局提供了图纸。参见 [Angular Material 文档](https://material.angular.io/guides "Angular Material documentation")。
</div>
@ -249,10 +259,14 @@ Any files outside of this folder are meant to support building your app.
</div>
<div class="file">browserslist</div>
<div class="file">favicon.ico</div>
<div class="file">index.html</div>
<div class="file">karma.conf.js</div>
<div class="file">main.ts</div>
<div class="file">polyfills.ts</div>
@ -265,6 +279,8 @@ Any files outside of this folder are meant to support building your app.
<div class="file">tsconfig.spec.json</div>
<div class="file">tslint.json</div>
</div>
</div>
@ -383,6 +399,23 @@ Any files outside of this folder are meant to support building your app.
</td>
</tr>
<tr>
<td>
`browserslist`
</td>
<td>
A configuration file to share [target browsers](https://github.com/browserslist/browserslist) between different front-end tools.
一个配置文件,用来在不同的前端工具之间共享[目标浏览器](https://github.com/browserslist/browserslist)。
</td>
</tr>
<tr>
<td>
@ -424,6 +457,24 @@ Any files outside of this folder are meant to support building your app.
</td>
</tr>
<tr>
<td>
`karma.conf.js`
</td>
<td>
Unit test configuration for the [Karma test runner](https://karma-runner.github.io),
used when running `ng test`.
给[Karma](https://karma-runner.github.io)的单元测试配置,当运行 `ng test` 时会用到它。
</td>
</tr>
<tr>
<td>
@ -527,6 +578,26 @@ Any files outside of this folder are meant to support building your app.
</td>
</tr>
<tr>
<td>
`tslint.json`
</td>
<td>
Additional Linting configuration for [TSLint](https://palantir.github.io/tslint/) together with
[Codelyzer](http://codelyzer.com/), used when running `ng lint`.
Linting helps keep your code style consistent.
额外的 Linting 配置。当运行 `ng lint` 时,它会供带有 [Codelyzer](http://codelyzer.com/) 的 [TSLint](https://palantir.github.io/tslint/) 使用。
Linting 可以帮你们保持代码风格的一致性。
</td>
</tr>
</table>
### The root folder
@ -550,30 +621,40 @@ These files go in the root folder next to `src/`.
<div class='children'>
<div class="file">app.e2e-spec.ts</div>
<div class="file">src</div>
<div class="file">app.po.ts</div>
<div class='children'>
<div class="file">app.e2e-spec.ts</div>
<div class="file">app.po.ts</div>
</div>
<div class="file">tsconfig.e2e.json</div>
<div class="file">protractor.conf.js</div>
</div>
<div class="file">node_modules/...</div>
<div class="file">src/...</div>
<div class="file">.angular-cli.json</div>
<div class='children'>
<div class="file">karma.conf.js</div>
</div>
<div class="file">.editorconfig</div>
<div class="file">.gitignore</div>
<div class="file">karma.conf.js</div>
<div class="file">angular.json</div>
<div class="file">package.json</div>
<div class="file">protractor.conf.js</div>
<div class="file">README.md</div>
<div class="file">tsconfig.json</div>
@ -651,28 +732,6 @@ These files go in the root folder next to `src/`.
</td>
</tr>
<tr>
<td>
`.angular-cli.json`
</td>
<td>
Configuration for Angular CLI.
In this file you can set several defaults and also configure what files are included
when your project is built.
Check out the official documentation if you want to know more.
Angular CLI 的配置文件。
在这个文件中,你可以设置一系列默认值,还可以配置项目编译时要包含的那些文件。
要了解更多,请参阅它的官方文档。
</td>
</tr>
<tr>
@ -705,7 +764,7 @@ These files go in the root folder next to `src/`.
<td>
Git configuration to make sure autogenerated files are not commited to source control.
Git configuration to make sure autogenerated files are not committed to source control.
一个 Git 的配置文件,用来确保某些自动生成的文件不会被提交到源码控制系统中。
@ -716,16 +775,20 @@ These files go in the root folder next to `src/`.
<td>
`karma.conf.js`
`angular.json`
</td>
<td>
Unit test configuration for the [Karma test runner](https://karma-runner.github.io),
used when running `ng test`.
Configuration for Angular CLI.
In this file you can set several defaults and also configure what files are included
when your project is built.
Check out the official documentation if you want to know more.
给[Karma](https://karma-runner.github.io)的单元测试配置,当运行 `ng test` 时会用到它。
Angular CLI 的配置文件。
在这个文件中,你可以设置一系列默认值,还可以配置项目编译时要包含的那些文件。
要了解更多,请参阅它的官方文档。
</td>

View File

@ -53,28 +53,28 @@ To preserve app integrity, the Angular service worker groups all files into a ve
任何时候,只要这个版本的 `index.html` 被提供了,与它对应的 `bundle.js` 也必须同时提供。
这种情况下,使用调用了 `startApp()` 的老的 `index.html` 并同时使用定义了 `runApp()` 的新 bundle 就是无效的。
This file integrity is especially important when lazy loading modules.
A JS bundle may reference many lazy chunks, and the filenames of the
lazy chunks are unique to the particular build of the app. If a running
app at version `X` attempts to load a lazy chunk, but the server has
This file integrity is especially important when lazy loading modules.
A JS bundle may reference many lazy chunks, and the filenames of the
lazy chunks are unique to the particular build of the app. If a running
app at version `X` attempts to load a lazy chunk, but the server has
updated to version `X + 1` already, the lazy loading operation will fail.
当使用惰性加载模块时,文件的整体性就显得格外重要。
某个 JS 包可能引用很多惰性块,而这些惰性块的文件名在应用的每次特定的构建中都是唯一的。
如果运行应用的 `X` 版本视图加载一个惰性块,但该块的服务器已经升级到了 `X + 1`版本,这次惰性加载操作就会失败。
The version identifier of the app is determined by the contents of all
resources, and it changes if any of them change. In practice, the version
is determined by the contents of the `ngsw.json` file, which includes
hashes for all known content. If any of the cached files change, the file's
hash will change in `ngsw.json`, causing the Angular service worker to
treat the active set of files as a new version.
The version identifier of the app is determined by the contents of all
resources, and it changes if any of them change. In practice, the version
is determined by the contents of the `ngsw.json` file, which includes
hashes for all known content. If any of the cached files change, the file's
hash will change in `ngsw.json`, causing the Angular service worker to
treat the active set of files as a new version.
本应用的版本标识符由其所有资源的内容决定,如果它们中的任何一个发生了变化,则版本标识符也随之改变。
实际上,版本是由 `ngsw.json` 文件的内容决定的,包含了所有已知内容的哈希值。
如果任何一个被缓存的文件发生了变化,则该文件的哈希也将在`ngsw.json`中随之变化,从而导致 Angular Service Worker 将这个活动文件的集合视为一个新版本。
With the versioning behavior of the Angular service worker, an application
With the versioning behavior of the Angular service worker, an application
server can ensure that the Angular app always has a consistent set of files.
借助 Angular Service Worker 的这种版本控制行为,应用服务器就可以确保这个 Angular 应用中的这组文件始终保持一致。
@ -95,33 +95,33 @@ the next time the application is loaded.
### 资源整体性
One of the potential side effects of long caching is inadvertently
caching an invalid resource. In a normal HTTP cache, a hard refresh
or cache expiration limits the negative effects of caching an invalid
file. A service worker ignores such constraints and effectively long
caches the entire app. Consequently, it is essential that the service worker
get the correct content.
One of the potential side effects of long caching is inadvertently
caching an invalid resource. In a normal HTTP cache, a hard refresh
or cache expiration limits the negative effects of caching an invalid
file. A service worker ignores such constraints and effectively long
caches the entire app. Consequently, it is essential that the service worker
gets the correct content.
长周期缓存的潜在副作用之一就是可能无意中缓存了无效的资源。
在普通的HTTP缓存中硬刷新或缓存过期限制了缓存这种无效文件导致的负面影响。
而 Service Worker 会忽略这样的约束,事实上会对整个应用程序进行长期缓存。
因此,让 Service Worker 获得正确的内容就显得至关重要。
To ensure resource integrity, the Angular service worker validates
the hashes of all resources for which it has a hash. Typically for
a CLI app, this is everything in the `dist` directory covered by
To ensure resource integrity, the Angular service worker validates
the hashes of all resources for which it has a hash. Typically for
a CLI app, this is everything in the `dist` directory covered by
the user's `src/ngsw-config.json` configuration.
为了确保资源的整体性Angular Service Worker 会验证所有带哈希的资源的哈希值。
通常,对于 CLI 应用程序,用户的 `src/ngsw-config.json` 配置文件中会涵盖 `dist` 目录下的所有内容。
If a particular file fails validation, the Angular service worker
attempts to re-fetch the content using a "cache-busting" URL
parameter to eliminate the effects of browser or intermediate
caching. If that content also fails validation, the service worker
considers the entire version of the app to be invalid and it stops
serving the app. If necessary, the service worker enters a safe mode
where requests fall back on the network, opting not to use its cache
If a particular file fails validation, the Angular service worker
attempts to re-fetch the content using a "cache-busting" URL
parameter to eliminate the effects of browser or intermediate
caching. If that content also fails validation, the service worker
considers the entire version of the app to be invalid and it stops
serving the app. If necessary, the service worker enters a safe mode
where requests fall back on the network, opting not to use its cache
if the risk of serving invalid, broken, or outdated content is high.
如果某个特定的文件未能通过验证Angular Service Worker 就会尝试用 “cache-busting” URL 为参数重新获取内容,以消除浏览器或中间缓存的影响。
@ -150,24 +150,24 @@ Hash mismatches can occur for a variety of reasons:
#### 不带哈希的内容
The only resources that have hashes in the `ngsw.json`
manifest are resources that were present in the `dist`
directory at the time the manifest was built. Other
resources, especially those loaded from CDNs, have
content that is unknown at build time or are updated
The only resources that have hashes in the `ngsw.json`
manifest are resources that were present in the `dist`
directory at the time the manifest was built. Other
resources, especially those loaded from CDNs, have
content that is unknown at build time or are updated
more frequently than the app is deployed.
`ngsw.json` 清单中唯一带哈希值的资源就是构建清单时 `dist` 目录中的资源。
而其他资源,特别是从 CDN 加载的资源,其内容在构建时是未知的,或者会比应用程序部署得更频繁。
If the Angular service worker does not have a hash to validate
a given resource, it still caches its contents but it honors
the HTTP caching headers by using a policy of "stale while
revalidate." That is, when HTTP caching headers for a cached
resource indicate that the resource has expired, the Angular
service worker continues to serve the content and it attempts
to refresh the resource in the background. This way, broken
unhashed resources do not remain in the cache beyond their
If the Angular service worker does not have a hash to validate
a given resource, it still caches its contents but it honors
the HTTP caching headers by using a policy of "stale while
revalidate." That is, when HTTP caching headers for a cached
resource indicate that the resource has expired, the Angular
service worker continues to serve the content and it attempts
to refresh the resource in the background. This way, broken
unhashed resources do not remain in the cache beyond their
configured lifetimes.
如果 Angular Service Worker 没有哈希可以验证给定的资源,它仍然会缓存它的内容,但会使用 “重新验证时失效” 的策略来承认HTTP缓存头。
@ -180,36 +180,36 @@ configured lifetimes.
### App 选项卡
It can be problematic for an app if the version of resources
it's receiving changes suddenly or without warning. See the
[Versions](guide/service-worker-devops#versions) section above
It can be problematic for an app if the version of resources
it's receiving changes suddenly or without warning. See the
[Versions](guide/service-worker-devops#versions) section above
for a description of such issues.
如果应用程序的资源版本突然发生了变化或没有给出警告,就可能会有问题。有关这些问题的描述,请参阅前面的 [版本](guide/service-worker-devops#versions) 部分。
The Angular service worker provides a guarantee: a running app
will continue to run the same version of the app. If another
instance of the app is opened in a new web browser tab, then
the most current version of the app is served. As a result,
that new tab can be running a different version of the app
The Angular service worker provides a guarantee: a running app
will continue to run the same version of the app. If another
instance of the app is opened in a new web browser tab, then
the most current version of the app is served. As a result,
that new tab can be running a different version of the app
than the original tab.
Angular Service Worker 会保证:正在运行的应用程序会继续运行和当前应用相同的版本。
而如果在新的 Web 浏览器选项卡中打开了该应用的另一个实例,则会提供该应用的最新版本。
因此,这个新标签可以和原始标签同时运行不同版本的应用。
It's important to note that this guarantee is **stronger**
than that provided by the normal web deployment model. Without
a service worker, there is no guarantee that code lazily loaded
later in a running app is from the same version as the initial
It's important to note that this guarantee is **stronger**
than that provided by the normal web deployment model. Without
a service worker, there is no guarantee that code lazily loaded
later in a running app is from the same version as the initial
code for the app.
值得注意的是,这种担保比普通的 Web 部署模型提供的担保还要**更强一点**。
如果没有 Service Worker则不能保证稍后在这个正在运行的应用中惰性加载的代码
和其初始代码的版本是一样的。
There are a few limited reasons why the Angular service worker
might change the version of a running app. Some of them are
There are a few limited reasons why the Angular service worker
might change the version of a running app. Some of them are
error conditions:
Angular Service Worker 为什么可能会更改运行中的应用的版本有几个有限的原因。
@ -223,14 +223,14 @@ Angular Service Worker 为什么可能会更改运行中的应用的版本有几
某个无关的错误导致 Service Worker 进入了安全模式,或者说,它被暂时禁用了。
The Angular service worker is aware of which versions are in
use at any given moment and it cleans up versions when
The Angular service worker is aware of which versions are in
use at any given moment and it cleans up versions when
no tab is using them.
Angular Service Worker 能知道在任何指定的时刻正在使用哪些版本,
并清除那些没有被任何选项卡使用的版本。
Other reasons the Angular service worker might change the version
Other reasons the Angular service worker might change the version
of a running app are normal events:
另一些可能导致 Angular Service Worker 在运行期间改变版本的因素是一些正常事件:
@ -247,23 +247,23 @@ of a running app are normal events:
### Service Worker 更新
The Angular service worker is a small script that runs in web browsers.
From time to time, the service worker will be updated with bug
fixes and feature improvements.
The Angular service worker is a small script that runs in web browsers.
From time to time, the service worker will be updated with bug
fixes and feature improvements.
Angular Service Worker 是一个运行在Web浏览器中的小脚本。
有时,这个 Service Worker 也可能会需要更新,以修复错误和增强特性。
The Angular service worker is downloaded when the app is first opened
and when the app is accessed after a period of inactivity. If the
service worker has changed, the service worker will be updated in the background.
The Angular service worker is downloaded when the app is first opened
and when the app is accessed after a period of inactivity. If the
service worker has changed, the service worker will be updated in the background.
首次打开应用时或在一段非活动时间之后再访问应用程序时,就会下载 Angular Service Worker。 如果 Service Worker 发生了变化Service Worker 就会在后台进行更新。
Most updates to the Angular service worker are transparent to the
app&mdash;the old caches are still valid and content is still served
normally. However, occasionally a bugfix or feature in the Angular
service worker requires the invalidation of old caches. In this case,
Most updates to the Angular service worker are transparent to the
app&mdash;the old caches are still valid and content is still served
normally. However, occasionally a bugfix or feature in the Angular
service worker requires the invalidation of old caches. In this case,
the app will be refreshed transparently from the network.
Angular Service Worker 的大部分更新对应用程序来说都是透明的 - 旧缓存仍然有效,其内容仍然能正常使用。
@ -274,10 +274,10 @@ Angular Service Worker 的大部分更新对应用程序来说都是透明的 -
## 调试 Angular Service Worker
Occasionally, it may be necessary to examine the Angular service
worker in a running state to investigate issues or to ensure that
it is operating as designed. Browsers provide built-in tools for
debugging service workers and the Angular service worker itself
Occasionally, it may be necessary to examine the Angular service
worker in a running state to investigate issues or to ensure that
it is operating as designed. Browsers provide built-in tools for
debugging service workers and the Angular service worker itself
includes useful debugging features.
偶尔,可能会需要检查运行中的 Angular Service Worker以调查问题或确保它在按设计运行。
@ -287,8 +287,8 @@ includes useful debugging features.
### 定位并分析调试信息
The Angular service worker exposes debugging information under
the `ngsw/` virtual directory. Currently, the single exposed URL
The Angular service worker exposes debugging information under
the `ngsw/` virtual directory. Currently, the single exposed URL
is `ngsw/state`. Here is an example of this debug page's contents:
Angular Service Worker 会在虚拟目录 `ngsw/` 下暴露出调试信息。
@ -322,7 +322,7 @@ Debug log:
#### 驱动程序的状态
The first line indicates the driver state:
The first line indicates the driver state:
第一行表示驱动程序的状态:
@ -332,7 +332,7 @@ Driver state: NORMAL ((nominal))
```
`NORMAL` indicates that the service worker is operating normally and is not in a degraded state.
`NORMAL` indicates that the service worker is operating normally and is not in a degraded state.
`NORMAL` 表示这个 Service Worker 正在正常运行,并且没有处于降级运行的状态。
@ -340,25 +340,25 @@ There are two possible degraded states:
有两种可能的降级状态:
* `EXISTING_CLIENTS_ONLY`: the service worker does not have a
clean copy of the latest known version of the app. Older cached
versions are safe to use, so existing tabs continue to run from
* `EXISTING_CLIENTS_ONLY`: the service worker does not have a
clean copy of the latest known version of the app. Older cached
versions are safe to use, so existing tabs continue to run from
cache, but new loads of the app will be served from the network.
`EXISTING_CLIENTS_ONLY`:这个 Service Worker 没有该应用的最新已知版本的干净副本。
较旧的缓存版本可以被安全的使用,所以现有的选项卡将继续使用较旧的版本运行本应用,
但新的应用将从网络上加载。
* `SAFE_MODE`: the service worker cannot guarantee the safety of
using cached data. Either an unexpected error occurred or all
cached versions are invalid. All traffic will be served from the
* `SAFE_MODE`: the service worker cannot guarantee the safety of
using cached data. Either an unexpected error occurred or all
cached versions are invalid. All traffic will be served from the
network, running as little service worker code as possible.
`SAFE_MODE`Service Worker 不能保证使用缓存数据的安全性。
发生了意外错误或所有缓存版本都无效。
这时所有的流量都将从网络提供,尽量少运行 Service Worker 中的代码。
In both cases, the parenthetical annotation provides the
In both cases, the parenthetical annotation provides the
error that caused the service worker to enter the degraded state.
在这两种情况下,后面的括号注解中都会提供导致 Service Worker 进入降级状态的错误信息。
@ -387,7 +387,7 @@ Last update check: never
```
This indicates the last time the service worker checked for a new version, or update, of the app. `never` indicates that the service worker has never checked for an update.
This indicates the last time the service worker checked for a new version, or update, of the app. `never` indicates that the service worker has never checked for an update.
这表示 Service Worker 最后一次检查应用程序的新版本或更新的时间。“never” 表示 Service Worker 从未检查过更新。
@ -407,10 +407,10 @@ Clients: 7b79a015-69af-4d3d-9ae6-95ba90c79486, 5bc08295-aaf2-42f3-a4cc-9e4ef9100
```
In this example, the service worker has one version of the app cached and
being used to serve two different tabs. Note that this version hash
is the "latest manifest hash" listed above. Both clients are on the
latest version. Each client is listed by its ID from the `Clients`
In this example, the service worker has one version of the app cached and
being used to serve two different tabs. Note that this version hash
is the "latest manifest hash" listed above. Both clients are on the
latest version. Each client is listed by its ID from the `Clients`
API in the browser.
在这个例子中Service Worker 拥有一个版本的应用程序缓存并用它服务于两个不同的选项卡。
@ -432,20 +432,20 @@ Task queue:
```
The Idle Task Queue is the queue of all pending tasks that happen
in the background in the service worker. If there are any tasks
in the queue, they are listed with a description. In this example,
the service worker has one such task scheduled, a post-initialization
The Idle Task Queue is the queue of all pending tasks that happen
in the background in the service worker. If there are any tasks
in the queue, they are listed with a description. In this example,
the service worker has one such task scheduled, a post-initialization
operation involving an update check and cleanup of stale caches.
空闲任务队列是 Service Worker 中所有在后台发生的未决任务的队列。
如果这个队列中存在任何任务,则列出它们的描述。
在这个例子中Service Worker 安排的任务是一个用于更新检查和清除过期缓存的后期初始化操作。
The last update tick/run counters give the time since specific
events happened related to the idle queue. The "Last update run"
counter shows the last time idle tasks were actually executed.
"Last update tick" shows the time since the last event after
The last update tick/run counters give the time since specific
events happened related to the idle queue. The "Last update run"
counter shows the last time idle tasks were actually executed.
"Last update tick" shows the time since the last event after
which the queue might be processed.
最后的 tick/run 计数器给出了与特定事件发生有关的空闲队列中的时间。
@ -470,26 +470,26 @@ Errors that occur within the service worker will be logged here.
### 开发者工具
Browsers such as Chrome provide developer tools for interacting
with service workers. Such tools can be powerful when used properly,
Browsers such as Chrome provide developer tools for interacting
with service workers. Such tools can be powerful when used properly,
but there are a few things to keep in mind.
Chrome 等浏览器提供了能与 Service Worker 交互的开发者工具。
这些工具在使用得当时非常强大,但也要牢记一些事情。
* When using developer tools, the service worker is kept running
* When using developer tools, the service worker is kept running
in the background and never restarts. This can cause behavior with Dev
Tools open to differ from behavior a user might experience.
使用开发人员工具时Service Worker 将继续在后台运行,并且不会重新启动。
这可能会导致开着 Dev Tools 时的行为与用户实际遇到的行为不一样。
* If you look in the Cache Storage viewer, the cache is frequently
* If you look in the Cache Storage viewer, the cache is frequently
out of date. Right click the Cache Storage title and refresh the caches.
如果你查看缓存存储器的查看器,缓存就会经常过期。右键单击缓存存储器的标题并刷新缓存。
Stopping and starting the service worker in the Service Worker
Stopping and starting the service worker in the Service Worker
pane triggers a check for updates.
在 Service Worker 页停止并重新启动这个 Service Worker 将会触发一次更新检查。
@ -498,24 +498,24 @@ pane triggers a check for updates.
## Service Worker 的安全性
Like any complex system, bugs or broken configurations can cause
the Angular service worker to act in unforeseen ways. While its
design attempts to minimize the impact of such problems, the
Angular service worker contains several failsafe mechanisms in case
Like any complex system, bugs or broken configurations can cause
the Angular service worker to act in unforeseen ways. While its
design attempts to minimize the impact of such problems, the
Angular service worker contains several failsafe mechanisms in case
an administrator ever needs to deactivate the service worker quickly.
像任何复杂的系统一样,错误或损坏的配置可能会导致 Angular Service Worker 以不可预知的方式工作。
虽然它在设计时就尝试将此类问题的影响降至最低,但是,如果管理员需要快速停用 Service Worker
Angular Service Worker 也包含多种故障保护机制。
## Fail-safe
### Fail-safe
## 故障保护机制
### 故障保护机制
To deactivate the service worker, remove or rename the
`ngsw-config.json` file. When the service worker's request
for `ngsw.json` returns a `404`, then the service worker
removes all of its caches and de-registers itself,
To deactivate the service worker, remove or rename the
`ngsw-config.json` file. When the service worker's request
for `ngsw.json` returns a `404`, then the service worker
removes all of its caches and de-registers itself,
essentially self-destructing.
要停用 Service Worker请删除或重命名 `ngsw-config.json` 文件。

View File

@ -2,6 +2,10 @@
# Service Worker 快速起步
This document explains how to enable Angular service worker support in your CLI projects. It then uses a simple example to show you a service worker in action, demonstrating loading and basic caching.
本文档解释了如何在 CLI 项目中启用对 Angular Service Worker 的支持。稍后它会用一个简单的范例来向你展示 Service Worker 实践,包括加载和基础的缓存功能。
#### Prerequisites
#### 前提条件
@ -14,147 +18,66 @@ A basic understanding of the following:
[Angular Service Worker 简介](guide/service-worker-intro).
* Angular v6, including Angular CLI v6.
Angular v6也包括 Angular CLI v6。
<hr />
Beginning in Angular 5.0.0, you can easily enable Angular service worker support in any CLI project. This document explains how to enable Angular service worker support in new and existing projects. It then uses a simple example to show you a service worker in action, demonstrating loading and basic caching.
## Adding a service worker to your project
从 Angular 5.0.0 开始,你就可以轻松为任何 CLI 项目启用 Angular Service Worker 的支持了。
这个文档解释了你要如何在新项目和现有项目中启用 Angular Service Worker 的支持。
然后使用一个简单的例子为你展示 Service Worker 实战,以演示加载和基本的缓存功能。
## 为你的项目添加 Service Worker
## Adding a service worker to a new application
To set up the Angular service worker in your project, use the CLI command `ng add @angular/pwa`. It takes care of configuring your app to use service workers by adding the `service-worker` package along
with setting up the necessary support files.
## 为新项目添加 Service Worker
If you're generating a new CLI project, you can use the CLI to set up the Angular service worker as part of creating the project. To do so, add the `--service-worker` flag to the `ng new` command:
如果你正在生成一个新的 CLI 项目,可以 使用 CLI 在创建项目时就准备好 Angular Service Worker。
只要在 `ng new` 命令中添加 `--service-worker` 标志就可以了:
要让你的项目支持 Angular Service Worker可以使用 CLI 命令 `ng add @angular/pwa`。它会添加 `service-worker` 包,并建立必要的支持文件,小心翼翼地配置你的应用,以便使用 Service Worker。
```sh
ng new my-project --service-worker
ng add @angular/pwa --project *project-name*
```
The `--service-worker` flag takes care of configuring your app to
use service workers by adding the `service-worker` package along
with setting up the necessary files to support service workers.
For information on the details, see the following section
which covers the process in detail as it shows you how to add a
service worker manually to an existing app.
The above command completes the following actions:
`--service-worker` 标志会通过添加 `service-worker` 包及其它必须的文件,来帮你配置好 Service Worker。
这个过程的细节和向现有项目中手动添加 Service Worker 的支持是一样的。要了解详情,参见下面的部分。
上述命令完成了如下步骤:
## Adding a service worker to an existing app
1. Adds the `@angular/service-worker` package to your project.
## 向现有工程中添加 Service Worker
@angular/service-worker 添加到你的项目中。
To add a service worker to an existing app:
要把 Service Worker 添加到现有应用中,就要:
1. Add the service worker package.
添加 Service Worker 包。
2. Enable service worker build support in the CLI.
2. Enables service worker build support in the CLI.
在 CLI 中启用 Service Worker 的构建支持。
3. Import and register the service worker.
3. Imports and registers the service worker in the app module.
导入并注册这个 Service Worker。
在应用模块中导入并注册 Service Worker。
4. Create the service worker configuration file, which specifies the caching behaviors and other settings.
4. Updates the `index.html` file:
创建 Service Worker 的配置文件,它指定了缓存行为和其它设置。
修改 `index.html` 文件:
5. Build the project.
* Includes a link to add the `manifest.json` file.
构建该项目
包含要添加到 `manifest.json` 文件中的链接
### Step 1: Add the service worker package
* Adds meta tags for `theme-color`.
`theme-color` 添加 meta 标签。
### 步骤 1添加 Service Worker 包
5. Installs icon files to support the installed Progressive Web App (PWA).
Add the package `@angular/service-worker`, using the yarn utility as shown here:
创建图标文件以支持安装渐进式应用PWA
添加 `@angular/service-worker` 包,使用 yarn 工具时的用法如下:
6. Creates the service worker configuration file called [`ngsw-config.json`](/guide/service-worker-config), which specifies the caching behaviors and other settings.
```sh
创建一个名叫 [`ngsw-config.json`](/guide/service-worker-config) 的 Service Worker 配置文件,它会用来指定缓存的行为以及其它设定。
yarn add @angular/service-worker
Now, build the project:
```
### Step 2: Enable service worker build support in the CLI
### 步骤 2在 CLI 中启用 Service Worker 的构建支持
To enable the Angular service worker, the CLI must generate an Angular service worker manifest at build time. To cause the CLI to generate the manifest for an existing project, set the `serviceWorker` flag to `true` in the project's `.angular-cli.json` file as shown here:
要启用 Angular Service WorkerCLI 必须在构建时生成一个 Angular Service Worker 的 `manifest` 文件。
要让 CLI 为现有项目生成 `manifest`,就要在该项目的 `.angular-cli.json` 文件中 `serviceWorker` 标识设置为 `true`。命令如下:
```sh
ng set apps.0.serviceWorker=true
```
### Step 3: Import and register the service worker
### 步骤 3导入并注册 Service Worker
To import and register the Angular service worker:
要导入并注册 Angular Service Worker 就要:
At the top of the root module, `src/app/app.module.ts`, import `ServiceWorkerModule` and `environment`.
在根模块 `src/app/app.module.ts` 的顶部导入 `ServiceWorkerModule``environment`
<code-example path="service-worker-getting-started/src/app/app.module.ts" linenums="false" title="src/app/app.module.ts" region="sw-import"> </code-example>
Add `ServiceWorkerModule` to the `@NgModule` `imports` array. Use the `register()` helper to take care of registering the service worker, taking care to disable the service worker when not running in production mode.
`ServiceWorkerModule` 添加到 `@NgModule``imports` 数组中。使用 `register()` 来帮助管理 Service Worker 的注册并在非生产环境下运行时禁用 Service Worker。
<code-example path="service-worker-getting-started/src/app/app.module.ts" linenums="false" title="src/app/app.module.ts" region="sw-module"> </code-example>
The file `ngsw-worker.js` is the name of the prebuilt service worker script, which the CLI copies into `dist/` to deploy along with your server.
`ngsw-worker.js` 文件是内置的 Service Worker 脚本的名字CLI 会把它复制到 `dist/` 目录下,让它随你的服务器一起发布。
### Step 4: Create the configuration file, `ngsw-config.json`
### 步骤 4创建配置文件 `ngsw-config.json`
The Angular CLI needs a service worker configuration file, called `ngsw-config.json`. The configuration file controls how the service worker caches files and data
resources.
Angular CLI 需要一个名叫 `ngsw-config.json` 的 Service Worker 配置文件。
这个配置文件会控制 Service Worker 如何缓存各个文件和数据资源。
You can begin with the boilerplate version from the CLI, which configures sensible defaults for most applications.
你可以从 CLI 创建的样板项目开始,它已经配置好了适合大多数应用的默认选项。
Alternately, save the following as `src/ngsw-config.json`:
另外,你也可以把下列内容保存为 `src/ngsw-config.json`
<code-example path="service-worker-getting-started/src/ngsw-config.json" linenums="false" title="src/ngsw-config.json"> </code-example>
### Step 5: Build the project
### 步骤 5构建本项目
Finally, build the project:
最后,构建本项目:
现在,构建本项目:
```sh
@ -179,7 +102,7 @@ using an example application.
### 用 `http-server` 启动开发服务器
Because `ng serve` does not work with service workers, you must use a seperate HTTP server to test your project locally. You can use any HTTP server. The example below uses the [http-server](https://www.npmjs.com/package/http-server) package from npm. To reduce the possibility of conflicts, test on a dedicated port.
Because `ng serve` does not work with service workers, you must use a separate HTTP server to test your project locally. You can use any HTTP server. The example below uses the [http-server](https://www.npmjs.com/package/http-server) package from npm. To reduce the possibility of conflicts, test on a dedicated port.
由于 `ng serve` 对 Service Worker 无效,所以必须用一个独立的 HTTP 服务器在本地测试你的项目。
你可以使用任何 HTTP 服务器。下面这个例子使用来自 npm 中的 [http-server](https://www.npmjs.com/package/http-server) 包。

View File

@ -65,12 +65,13 @@ Angular 的 Service Worker 的行为遵循下列设计目标:
只要有可能Service Worker 就会尽量节省带宽。它只会下载那些发生了变化的资源。
To support these behaviors, the Angular service worker loads a *manifest* file from the server. The manifest describes the resources to cache and includes hashes of every file's contents. When an update to the application is deployed, the contents of the manifest change, informing the service worker that a new version of the application should be downloaded and cached. This manifest is generated from a user-provided configuration file called `ngsw-config.json`, by using a build tool such as the Angular CLI.
To support these behaviors, the Angular service worker loads a *manifest* file from the server. The manifest describes the resources to cache and includes hashes of every file's contents. When an update to the application is deployed, the contents of the manifest change, informing the service worker that a new version of the application should be downloaded and cached. This manifest is generated from a CLI-generated configuration file called `ngsw-config.json`.
要支持这些行为Angular 的 Service Worker 会从服务器上下载一个 `manifest` 文件。
这个 `manifest` 文件描述要缓存的资源,并包含每个文件内容的哈希值。
当发布了应用的一个新版本时,`manifest` 的内容就会改变,通知 Service Worker 应该下载并缓存应用的一个新版本了。
这个 manifest 是从用户使用 Angular CLI 等构建工具提供的一个名叫 `ngsw-config.json` 的文件中生成的。
这个 manifest 是从 CLI 生成的一个名叫 `ngsw-config.json` 的文件中生成的。
Installing the Angular service worker is as simple as including an `NgModule`. In addition to registering the Angular service worker with the browser, this also makes a few services available for injection which interact with the service worker and can be used to control it. For example, an application can ask to be notified when a new update becomes available, or an application can ask the service worker to check the server for available updates.
@ -82,18 +83,6 @@ Installing the Angular service worker is as simple as including an `NgModule`. I
## 前提条件
To use Angular service workers, you must have the following Angular and CLI versions:
要想使用 Angular Service Worker你要使用下列 Angular 和 CLI 版本:
* Angular 5.0.0 or later.
Angular 5.0.0 或更高。
* Angular CLI 1.6.0 or later.
Angular CLI 1.6.0 或更高。
Your application must run in a web browser that supports service workers. Currently, the latest versions of Chrome and Firefox are supported. To learn about other browsers that are service worker ready, see the [Can I Use](http://caniuse.com/#feat=serviceworkers) page.
你的应用必须运行在支持 Service Worker 的 Web 浏览器中。目前Chrome 和 Firefox 的最新版本 都已经支持了。

View File

@ -17,9 +17,9 @@ maintained [on github](https://github.com/angular/quickstart "Install the github
利用 [github 上](https://github.com/angular/quickstart "安装 github 《快速上手》库")的**《快速上手》种子**在你的电脑上搭建一个新项目是很快很容易的。
Make sure you have [node and npm installed](guide/setup#install-prerequisites "What if you don't have node and npm?").
Make sure you have [Node.js® and npm installed](guide/setup#install-prerequisites "What if you don't have Node.js and npm?").
确定你已经安装了 [node 和 npm](guide/setup#install-prerequisites "如果你没有 node 和 npm")。
确定你已经安装了 [Node.js® 和 npm](guide/setup#install-prerequisites "如果你没有 Node.js 和 npm")。
{@a clone}
@ -336,35 +336,33 @@ If you're new to Angular, we recommend you follow the [tutorial](tutorial "Tour
{@a install-prerequisites}
## Appendix: node and npm
## Appendix: Node.js and npm
## 附录node 与 npm
Node.js and npm are essential to modern web development with Angular and other platforms.
Node powers client development and build tools.
The _npm_ package manager, itself a _node_ application, installs JavaScript libraries.
[Node.js](https://nodejs.org/en/) and the [npm](https://www.npmjs.com/) package manager are essential to modern web development with Angular and other platforms.
Node.js powers client development and build tools.
The _npm_ package manager, which is itself a _Node.js_ application, installs JavaScript libraries.
Node.js 和 npm 对使用 Angular 和其他平台进行现代网络开发是至关重要的。
Node 驱动客户端开发和构建工具。
*npm* 包管理器本身是 *node* 应用,用于安装 JavaScript 库。
[Node.js](https://nodejs.org/en/) 和 [npm](https://www.npmjs.com/) 包管理器对使用 Angular 和其他平台进行现代网络开发是至关重要的。
Node.js 用来支持客户端开发和构建工具。*npm* 包管理器本身就是一个 *Node.js* 应用,用于安装 JavaScript 库。
<a href="https://docs.npmjs.com/getting-started/installing-node" target="_blank" title="Installing Node.js and updating npm">Get them now</a> if they're not already installed on your machine.
如果你的电脑没有安装它们,请<a href="https://docs.npmjs.com/getting-started/installing-node" target="_blank" title="安装 Node.js 和更新 npm">现在安装</a>
**Verify that you are running node `v4.x.x` or higher and npm `3.x.x` or higher**
**Verify that you are running Node.js `v8.x` or higher and npm `5.x` or higher**
by running the commands `node -v` and `npm -v` in a terminal/console window.
Older versions produce errors.
在终端/控制器窗口运行命令 `node -v``npm -v`,来**确认你运行的 node 是 `v4.x.x` 或更高npm 为 `3.x.x` 或更高。**
在终端/控制器窗口运行命令 `node -v``npm -v`,来**确认你运行的 Node.js 是 `v8.x` 或更高npm 为 `5.x` 或更高。**
老版本会产生错误。
We recommend [nvm](https://github.com/creationix/nvm) for managing multiple versions of node and npm.
You may need [nvm](https://github.com/creationix/nvm) if you already have projects running on your machine that
use other versions of node and npm.
We recommend [nvm](https://github.com/creationix/nvm) for managing multiple versions of Node.js and npm.
You may need [nvm](https://github.com/creationix/nvm) if you already have projects running on your machine that use other versions of Node.js and npm.
我们推荐使用 [nvm](https://github.com/creationix/nvm) 来管理多版本 node 和 npm。
如果你的电脑上已经有使用其他版本 node 和 npm 的项目,你可能需要 nvm。
我们推荐使用 [nvm](https://github.com/creationix/nvm) 来管理多版本 Node.js 和 npm。
如果你的电脑上已经有使用其他版本 Node.js 和 npm 的项目,你可能需要 nvm。
{@a why-locally}

View File

@ -25,67 +25,23 @@ For a sample app using the app-wide singleton service that this page describes,
## 提供单例服务
An injector created from a module definition will have services which are singletons with respect to
that injector. To control the lifetime of services, one controls the creation and destruction of
injectors. For example, a route will have an associated module. When the route is activated, an
injector is created from that module as a child of the current injector. When you navigate away from
the route, the injector is destroyed. This means that services declared in a route module will have
a lifetime equal to that of the route. Similarly, services provided in an application module will
have the same lifetime of the application, hence singleton.
There are two ways to make a service a singleton in Angular:
那些在定义模块时创建的注入器将会拥有一些服务,这些服务对于该注入器来说都是单例的。要控制这些服务的生命周期,其实就是控制注入器的创建和销毁。
比如,路由定义中就可以有一个关联模块。当激活该路由时,就会给那个模块创建一个新注入器,并将其作为当前注入器的子注入器。当离开该路由时,这个新注入器也就被销毁了。
这也意味着在这个模块中声明的那些服务也随之销毁了,它们的生命周期与该路由完全相同。
类似的,在应用模块中提供的那些服务的生命周期也等同于该应用,因此是单例的。
在 Angular 中有两种方式来生成单例服务:
The following example module is called, as a convention, `CoreModule`. This use of `@NgModule` creates organizational infrastructure and gives you
a way of providing services from a designated NgModule.
* Declare that the service should be provided in the application root.
下面的范例模块习惯上叫做 `CoreModule`。`@NgModule` 用来创建结构良好的基础设施,让你能够在一个指定的模块中提供服务
声明该服务应该在应用的根上提供。
<code-example path="ngmodules/src/app/core/core.module.ts" region="user-service" title="src/app/core/core.module.ts" linenums="false">
</code-example>
* Include the service in the `AppModule` or in a module that is only imported by the `AppModule`.
Here, `CoreModule` provides the `UserService`, and because `AppModule`
imports `CoreModule`, any services that `CoreModule` provides are available
throughout the app, because it is a root of the injector tree. It will also be a singleton because the injector lifetime of the `AppModule` is for the duration of the application.
把该服务包含在 `AppModule` 或某个只会被 `AppModule` 导入的模块中。
这里的 `CoreModule` 提供了 `UserService`,并且由于 `AppModule` 导入了 `CoreModule`,所以 `CoreModule` 中提供的任何服务也能在整个应用中使用,因为它是注入器树的根节点。
它还是单例的,因为在该应用运行期间,该注入器的生命周期等同于 `AppModule` 的。
Beginning with Angular 6.0, the preferred way to create a singleton services is to specify on the service that it should be provided in the application root. This is done by setting `providedIn` to `root` on the service's `@Injectable` decorator:
Angular registers the `UserService` provider with the app root
injector, making a singleton instance of the `UserService`
available to any component that needs it,
whether that component is eagerly or lazily loaded.
从 Angular 6.0 开始,创建单例服务的首选方式是在那个服务类上指定它应该在应用的根上提供。只要在该服务的 `@Injectable` 装饰器上把 `providedIn` 设置为 `root` 就可以了:
Angular 使用应用的根注入器注册了 `UserService` 提供商,可以让任何需要它的组件(无论它是立即加载的还是惰性加载的)都能使用 `UserService` 的单例。
The root `AppModule` could register the `UserService` directly,
but as the app grows, it could have other services and
components like spinners, modals, and so on. To
keep your app organized, consider using a module such as `CoreModule`.
This technique simplifies the root `AppModule` in its
capacity as orchestrator of the application as a whole.
根模块 `AppModule` 当然也可以直接注册 `UserService`,不过随着应用的成长,可能还会出现其它的服务和组件,比如 列表框、模态框等等。
要想保持你应用的良好结构,就要考虑使用诸如 `CoreModule` 这样的模块。
这种方式简化了根模块 `AppModule`,让它只需要扮演整个应用的总指挥,而不必事必躬亲。
Now you can inject such services into components as needed. In terms of
Angular NgModules, you only need to define the services in one `@NgModule`.
See [JS Modules vs. NgModules](guide/ngmodule-vs-jsmodule) for
more information on how to differentiate between the two.
现在,你可以把这些服务注入到需要它们的各个组件中了。
从 Angular 模块的角度来说,你只需要把这些服务定义在一个 `@NgModule` 中。
要想深入了解两者的区别,参见 [JS 模块 vs. NgModule](guide/ngmodule-vs-jsmodule)。
As a general rule, import modules with providers _exactly once_,
preferably in the application's _root module_.
That's also usually the best place to configure, wrap, and override them.
作为一个通用的规则,应该*只导入一次*带提供商的模块,最好在应用的*根模块*中。
那里也是配置、包装和改写这些服务的最佳位置。
<code-example path="providers/src/app/user.service.0.ts" title="src/app/user.service.0.ts" linenums="false"> </code-example>
For more detailed information on services, see the [Services](tutorial/toh-pt4) chapter of the
[Tour of Heroes tutorial](tutorial).

View File

@ -4328,9 +4328,9 @@ Compare with the less preferred `host` metadata alternative.
<div class="s-rule do">
**Do** provide services to the Angular injector at the top-most component where they will be shared.
**Do** provide a service with the app root injector in the `@Injectable` decorator of the service.
**坚持**将服务提供到共享范围内的顶级组件的 Angular 注入器
**坚持**在服务的 `@Injectable` 装饰器上指定通过应用的根注入器提供服务
</div>
@ -4344,18 +4344,17 @@ Compare with the less preferred `host` metadata alternative.
<div class="s-why">
**Why?** When providing the service to a top level component,
that instance is shared and available to all child components of that top level component.
**Why?** When you provide the service to a root injector, that instance of the service is shared and available in every class that needs the service. This is ideal when a service is sharing methods or state.
**为何?**在顶层组件提供服务时,该服务实例在所有子组件中可见并共享
**为何?**当你在根注入器上提供该服务时,该服务实例在每个需要该服务的类中是共享的。当服务要共享方法或状态时,这是最理想的选择
</div>
<div class="s-why">
**Why?** This is ideal when a service is sharing methods or state.
**Why?** When you register a service in the `@Injectable` decorator of the service, optimization tools such as those used by the CLI's production builds can perform tree shaking and remove services that aren't used by your app.
**为何?**服务是共享方法或状态的理想载体
**为何?**当你在服务的 `@Injectable` 中注册服务时CLI 生产环境构建时使用的优化工具可以进行摇树优化,从而移除那些你的应用中从未用过的服务
</div>
@ -4367,17 +4366,7 @@ that instance is shared and available to all child components of that top level
</div>
<code-tabs>
<code-pane title="app/app.component.ts" path="styleguide/src/07-03/app/app.component.ts">
</code-pane>
<code-pane title="app/heroes/hero-list/hero-list.component.ts" path="styleguide/src/07-03/app/heroes/hero-list/hero-list.component.ts">
</code-pane>
</code-tabs>
<code-example path="dependency-injection/src/app/tree-shaking/service.ts" title="src/app/treeshaking/service.ts" linenums="false"> </code-example>
<a href="#toc">Back to top</a>

View File

@ -97,16 +97,16 @@ The CLI takes care of Jasmine and karma configuration for you.
CLI 会为你生成 Jasmine 和 Karma 的配置文件。
You can fine-tune many options by editing the `karma.conf.js` file in the project root folder and
the `test.ts` file in the `src/` folder.
You can fine-tune many options by editing the `karma.conf.js` and
the `test.ts` files in the `src/` folder.
不过你也可以通过编辑项目根目录下的 `karma.conf.js` 文件以及 `src/` 目录下的 `test.ts` 文件来微调很多选项。
不过你也可以通过编辑 `src/` 目录下的 `karma.conf.js` `test.ts` 文件来微调很多选项。
The `karma.conf.js` file is a partial karma configuration file.
The CLI constructs the full runtime configuration in memory,based on application structure specified in the `.angular-cli.json` file, supplemented by `karma.conf.js`.
The CLI constructs the full runtime configuration in memory,based on application structure specified in the `angular.json` file, supplemented by `karma.conf.js`.
`karma.conf.js` 文件是 karma 配置文件的一部分。
CLI 会基于 `.angular-cli.json` 文件中指定的项目结构和 `karma.conf.js` 文件,来在内存中构建出完整的运行时配置。
CLI 会基于 `angular.json` 文件中指定的项目结构和 `karma.conf.js` 文件,来在内存中构建出完整的运行时配置。
Search the web for more details about Jasmine and karma configuration.
@ -419,21 +419,19 @@ test any service with a dependency.
<div class="alert is-important">
The `HeroService` methods return _Observables_.
_Subscribe_ to the method observable to (a) cause it to execute and (b)
The `HeroService` methods return `Observables`. You must
_subscribe_ to an observable to (a) cause it to execute and (b)
assert that the method succeeds or fails.
`HttpService` 中的方法会返回*可观察对象*。*订阅*这些方法返回的可观察对象会让它开始执行,并且断言这些方法是成功了还是失败了。
The `subscribe()` method takes a success and fail callback.
Make sure you provide _both_ callbacks so that you capture errors.
`subscribe()` 方法接受一个成功回调和一个失败回调。
你要确保同时提供了这两个回调,以便捕获错误。
`HttpService` 中的方法会返回 `Observables`。*订阅*这些方法返回的可观察对象会让它开始执行,并且断言这些方法是成功了还是失败了。
The `subscribe()` method takes a success (`next`) and fail (`error`) callback.
Make sure you provide _both_ callbacks so that you capture errors.
Neglecting to do so produces an asynchronous uncaught observable error that
the test runner will likely attribute to a completely different test.
`subscribe()` 方法接受一个成功回调 (`next`) 和一个失败 (`error`) 回调。
你要确保同时提供了这两个回调,以便捕获错误。
如果忽略这些异步调用中未捕获的错误,测试运行器可能会得出截然不同的测试结论。
</div>
@ -1555,9 +1553,9 @@ Focus on the spy.
region="spy">
</code-example>
The spy is designed such that any call to `getQuote` receives an Observable with a test quote.
The spy is designed such that any call to `getQuote` receives an observable with a test quote.
Unlike the real `getQuote()` method, this spy bypasses the server
and returns a synchronous Observable whose value is available immediately.
and returns a synchronous observable whose value is available immediately.
这个间谍的设计是:任何对 `getQuote` 的调用都会收到一个包含测试引文的可观察对象。
和真正的 `getQuote()` 方法不同,这个间谍跳过了服务器,直接返回了一个能立即解析出值的同步型可观察对象。
@ -1701,20 +1699,21 @@ This helper's observable emits the `data` value in the next turn of the JavaScri
这个辅助函数的可观察对象会在 JavaScript 引擎的下一个工作周期中发出 `data` 的值。
[RxJS `defer()`](http://reactivex.io/documentation/operators/defer.html) returns an observable.
The [RxJS `defer()` operator](http://reactivex.io/documentation/operators/defer.html) returns an observable.
It takes a factory function that returns either a promise or an observable.
When something subscribes to _defer_'s observable,
it adds the subscriber to a new observable created with that factory.
[RxJS `defer()`](http://reactivex.io/documentation/operators/defer.html) (延期)返回一个可观察对象。
[RxJS `defer()` (延期)操作符](http://reactivex.io/documentation/operators/defer.html) 返回一个可观察对象。
它获取一个工厂函数,这个工厂函数或者返回 Promise 或者返回 Observable。
当有人订阅了这个 `defer` 的可观察对象时,它就会把这个订阅者添加到由那个工厂函数创建的新的可观察对象中。
RxJS `defer()` transform the `Promise.resolve()` into a new observable that,
like `HttpClient`, emits once and completes.
Subscribers will be unsubscribed after they receive the data value.
RxJS `defer()` 会把 `Promise.resolve()` 转换成一个新的可观察对象,然后像 `HttpClient` 那样的发出一个值,然后结束。
The `defer()` operator transforms the `Promise.resolve()` into a new observable that,
like `HttpClient`, emits once and completes.
Subscribers are unsubscribed after they receive the data value.
`defer()` 操作符会把 `Promise.resolve()` 转换成一个新的可观察对象,然后像 `HttpClient` 那样的发出一个值,然后结束。
订阅者将会在接收到这个数据值之后自动被取消订阅。
There's a similar helper for producing an async error.
@ -2578,13 +2577,11 @@ Here's the `HeroDetailComponent` constructor:
<code-example path="testing/src/app/hero/hero-detail.component.ts" region="ctor" title="app/hero/hero-detail.component.ts (constructor)" linenums="false"></code-example>
The `HeroDetail` component needs the `id` parameter so it can fetch
the corresponding hero via the `HeroDetailService`.
the corresponding hero via the `HeroDetailService`.
The component has to get the `id` from the `ActivatedRoute.paramMap` property
which is an `Observable`.
`HeroDetailComponent` 组件需要一个 `id` 参数,以便通过 `HeroDetailService` 获取相应的英雄。
The component has to get the `id` from the `ActivatedRoute.paramMap` property
which is an _Observable_.
该组件只能从 `ActivatedRoute.paramMap` 属性中获取这个 `id`,这个属性是一个 `Observable`
It can't just reference the `id` property of the `ActivatedRoute.paramMap`.
@ -3627,9 +3624,10 @@ Focus on the `overrideComponent` method.
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="override-component-method" title="app/hero/hero-detail.component.spec.ts (overrideComponent)" linenums="false"></code-example>
It takes two arguments: the component type to override (`HeroDetailComponent`) and an override metadata object.
The [overide metadata object](#metadata-override-object) is a generic defined as follows:
The [override metadata object](#metadata-override-object) is a generic defined as follows:
它接受两个参数:要改写的组件类(`HeroDetailComponent`),以及用于改写的元数据对象:
它接受两个参数:要改写的组件类型(`HeroDetailComponent`),以及用于改写的元数据对象。
[用于改写的元数据对象](#metadata-override-object)是一个泛型,其定义如下:
<code-example format="." language="javascript">
type MetadataOverride<T> = {

View File

@ -203,10 +203,10 @@ QuickStart identifies two *typings*, or `d.ts`, files:
[jasmine](http://jasmine.github.io/)是 Jasmine 测试框架的类型定义
* [node](https://www.npmjs.com/package/@types/node) for code that references objects in the *nodejs* environment;
* [node](https://www.npmjs.com/package/@types/node) for code that references objects in the *Node.js®* environment;
you can view an example in the [webpack](guide/webpack) page.
[node](https://www.npmjs.com/package/@types/node)是为了在 *nodejs* 环境中引用对象的代码提供的类型定义。在[webpack](guide/webpack)页面可以看到例子。
[node](https://www.npmjs.com/package/@types/node)是为了在 *Node.js®* 环境中引用对象的代码提供的类型定义。在[webpack](guide/webpack)页面可以看到例子。
QuickStart doesn't require these typings but many of the samples do.

View File

@ -30,9 +30,9 @@ Meanwhile, the browser downloads the full client version and switches to it auto
<div class="l-sub-section">
[Download the finished sample code](generated/zips/universal/universal.zip),
which runs in a [node express](https://expressjs.com/) server.
which runs in a [Node.js® Express](https://expressjs.com/) server.
你可以[下载最终的范例代码](generated/zips/universal/universal.zip),并将其运行在一个 [node express](https://expressjs.com/) 服务器中。
你可以[下载最终的范例代码](generated/zips/universal/universal.zip),并将其运行在一个 [Node.js® Express](https://expressjs.com/) 服务器中。
</div>
@ -227,10 +227,10 @@ You'll add more files to support building and serving with Universal.
In this example, the Angular CLI compiles and bundles the Universal version of the app with the
[AOT (Ahead-of-Time) compiler](guide/aot-compiler).
A node/express web server turns client requests into the HTML pages rendered by Universal.
A Node.js® Express web server turns client requests into the HTML pages rendered by Universal.
在这个例子中Angular CLI 会使用 [AOT (预先) 编译器](guide/aot-compiler)对该应用的 Universal 版本进行编译和打包。
Node 的 Express Web 服务器会把客户端请求转换成由 Universal 渲染出的页面。
Node.js® 的 Express Web 服务器会把客户端请求转换成由 Universal 渲染出的页面。
You will create:
@ -774,9 +774,9 @@ First add the _build_ and _serve_ commands to the `scripts` section of the `pack
<code-example format="." language="ts">
"scripts": {
...
"build:universal": "npm run build:client-and-server-bundles && npm run webpack:server",
"serve:universal": "node dist/server.js",
"build:client-and-server-bundles": "ng build --prod && ng build --prod --app 1 --output-hashing=false",
"build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server",
"serve:ssr": "node dist/server",
"build:client-and-server-bundles": "ng build --prod && ng run angular.io-example:server",
"webpack:server": "webpack --config webpack.server.config.js --progress --colors"
...
}
@ -793,7 +793,7 @@ From the command prompt, type
在命令行提示中输入
<code-example format="." language="bash">
npm run build:universal
npm run build:ssr
</code-example>
The Angular CLI compiles and bundles the universal app into two different folders, `browser` and `server`.
@ -813,7 +813,7 @@ After building the application, start the server.
构建完应用之后,启动服务器。
<code-example format="." language="bash">
npm run serve:universal
npm run serve:ssr
</code-example>
The console window should say

View File

@ -30,6 +30,22 @@ The Angular CLI generated a new project with a default application and supportin
这样 Angular CLI 就创建了一个带默认应用及其支持文件的新项目。
<div class="l-sub-section">
You can add pre-packaged functionality to a new project by using the `ng add` command. The `ng add` command transforms a project by applying the schematics in the specified package.
For more information, see the [Angular CLI documentation.](https://github.com/angular/angular-cli/wiki/add "Angular CLI documentation")
你可以使用 `ng add` 命令往新项目中添加一些预先打包好的功能。
`ng add` 命令会通过应用来自特定 NPM 包中的图纸schematic来转换此项目。
要了解更多,参见 [Angular CLI 文档](https://github.com/angular/angular-cli/wiki/add "Angular CLI documentation")。
Angular Material provides schematics for typical app layouts.
See the [Angular Material documentation](https://material.angular.io/guides "Angular Material documentation") for details.
比如 Angular Material 就为一些典型布局提供了图纸。参见 [Angular Material 文档](https://material.angular.io/guides "Angular Material documentation")。
</div>
## Serve the application
## 启动应用服务器

View File

@ -12,12 +12,12 @@ You'll want to split up large components into smaller sub-components, each focus
把所有特性都放在同一个组件中,将会使应用“长大”后变得不可维护。
你要把大型组件拆分成小一点的子组件,每个子组件都要集中精力处理某个特定的任务或工作流。
In this page, you'll take the first step in that direction by moving the hero details into a separate, reusable `HeroDetailsComponent`.
In this page, you'll take the first step in that direction by moving the hero details into a separate, reusable `HeroDetailComponent`.
本页面中,你将迈出第一步 —— 把英雄详情移入一个独立的、可复用的 `HeroDetailComponent`
The `HeroesComponent` will only present the list of heroes.
The `HeroDetailsComponent` will present details of a selected hero.
The `HeroDetailComponent` will present details of a selected hero.
`HeroesComponent` 将仅仅用来表示英雄列表。
`HeroDetailComponent` 将用来表示所选英雄的详情。

View File

@ -56,7 +56,7 @@ Using the Angular CLI, create a service called `hero`.
</code-example>
The command generates skeleton `HeroService` class in `src/app/hero.service.ts`
The `HeroService` class should look like the below.
The `HeroService` class should look like the following example.
该命令会在 `src/app/hero.service.ts` 中生成 `HeroService` 类的骨架。
`HeroService` 类的代码如下:
@ -70,27 +70,16 @@ The `HeroService` class should look like the below.
### _@Injectable()_ 服务
Notice that the new service imports the Angular `Injectable` symbol and annotates
the class with the `@Injectable()` decorator.
the class with the `@Injectable()` decorator. This marks the class as one that participates in the _dependency injection system_. The `HeroService` class is going to provide an injectable service, and it can also have its own injected dependencies.
It doesn't have any dependencies yet, but [it will soon](#inject-message-service).
注意,这个新的服务导入了 Angular 的 `Injectable` 符号,并且给这个服务类添加了 `@Injectable()` 装饰器。
The `@Injectable()` decorator tells Angular that this service _might_ itself
have injected dependencies.
It doesn't have dependencies now but [it will soon](#inject-message-service).
Whether it does or it doesn't, it's good practice to keep the decorator.
`@Injectable()` 装饰器告诉 Angular 这个服务本身*可能*拥有被注入的依赖。
它把这个类标记为*依赖注入系统*的参与者之一。`HeroService` 类将会提供一个可注入的服务,并且它还可以拥有自己的待注入的依赖。
目前它还没有依赖,但是[很快就会有了](#inject-message-service)。
无论它会不会有,总是给服务加上这个装饰器都是一种好的做法。
<div class="l-sub-section">
The `@Injectable()` decorator accepts a metadata object for the service, the same way the `@Component()` decorator did for your component classes.
The Angular [style guidelines](guide/styleguide#style-07-04) strongly recommend keeping it
and the linter enforces this rule.
Angular 的[风格指南](guide/styleguide#style-07-04)强烈建议加上,而且 linter代码检查器 也会确保这条规则。
</div>
`@Injectable()` 装饰器会接受该服务的元数据对象,就像 `@Component()` 对组件类的作用一样。
### Get hero data
@ -130,47 +119,59 @@ Add a `getHeroes` method to return the _mock heroes_.
## 提供provide `HeroService`
You must _provide_ the `HeroService` in the _dependency injection system_
You must make the `HeroService` available to the dependency injection system
before Angular can _inject_ it into the `HeroesComponent`,
as you will do [below](#inject).
as you will do [below](#inject). You do this by registering a _provider_. A provider is something that can create or deliver a service; in this case, it instantiates the `HeroService` class to provide the service.
在要求 Angular 把 `HeroService` 注入到 `HeroesComponent` 之前,你必须先把这个服务*提供给依赖注入系统*。[稍后](#inject)你就要这么做。
你可以通过注册*提供商*来做到这一点。提供商用来创建和交付服务,在这个例子中,它会对 `HeroService` 类进行实例化,以提供该服务。
There are several ways to provide the `HeroService`:
in the `HeroesComponent`, in the `AppComponent`, in the `AppModule`.
Each option has pros and cons.
Now, you need to make sure that the `HeroService` is registered as the provider of this service.
You are registering it with an _injector_, which is the object that is responsible for choosing and injecting the provider where it is required.
有很多途径可以提供 `HeroService`:在 `HeroesComponent` 中、在 `AppComponent` 中,或在 `AppModule`
每个选项都各有优缺点
现在,你需要确保 `HeroService` 已经作为该服务的提供商进行过注册
你要用一个*注入器*注册它。注入器就是一个对象,负责在需要时选取和注入该提供商
This tutorial chooses to provide it in the `AppModule`.
By default, the Angular CLI command `ng generate service` registers a provider with the _root injector_ for your service by including provider metadata in the `@Injectable` decorator.
这节课选择在 `AppModule` 中提供它
默认情况下Angular CLI 命令 `ng generate service` 会通过给 `@Injectable` 装饰器添加元数据的形式,为该服务把提供商注册到*根注入器*上
That's such a popular choice that you could have told the CLI to provide it there automatically
by appending `--module=app`.
If you look at the `@Injectable()` statement right before the `HeroService` class definition, you can see that the `providedIn` metadata value is 'root':
这是一个常用的选择,因此你可以通过 `--module=app` 选项让 CLI 自动把它提供给 `AppModule`
如果你看看 `HeroService` 紧前面的 `@Injectable()` 语句定义,就会发现 `providedIn` 元数据的值是 'root'
```
@Injectable({
providedIn: 'root',
})
```
When you provide the service at the root level, Angular creates a single, shared instance of `HeroService` and injects into any class that asks for it.
Registering the provider in the `@Injectable` metadata also allows Angular to optimize an app by removing the service if it turns out not to be used after all.
当你在顶层提供该服务时Angular 就会为 `HeroService` 创建一个单一的、共享的实例,并把它注入到任何想要它的类上。
`@Injectable` 元数据中注册该提供商,还能让 Angular 可以通过移除那些完全没有用过的服务,来进行优化。
<div class="l-sub-section">
If you need to, you can register providers at different levels:
in the `HeroesComponent`, in the `AppComponent`, in the `AppModule`.
For instance, you could have told the CLI to provide the service at the module level automatically by appending `--module=app`.
如果需要,你也可以在不同的层次上注册提供商 —— 在 `HeroesComponent` 中、在 `AppComponent` 中,或在 `AppModule` 中。
比如,你可以通过附加 `--module=app` 参数来告诉 CLI 要自动在模块级提供该服务。
<code-example language="sh" class="code-shell">
ng generate service hero --module=app
</code-example>
Since you did not, you'll have to provide it yourself.
To learn more about providers and injectors, see the [Dependency Injection guide](guide/dependency-injection).
如果不这样做,你就要自行提供它。
要了解更多,参见[依赖注入指南](guide/dependency-injection)
Open the `AppModule` class, import the `HeroService`, and add it to the `@NgModule.providers` array.
打开 `AppModule` 类,导入 `HeroService`,并把它加入 `@NgModule.providers` 数组中。
<code-example path="toh-pt4/src/app/app.module.ts" linenums="false" title="src/app/app.module.ts (providers)" region="providers-heroservice">
</code-example>
The `providers` array tells Angular to create a single, shared instance of `HeroService`
and inject into any class that asks for it.
`providers` 数组会告诉 Angular 创建 `HeroService` 的单一、共享的实例,并且把它注入到任何请求注入它的类中。
</div>
The `HeroService` is now ready to plug into the `HeroesComponent`.
@ -184,14 +185,6 @@ This is a interim code sample that will allow you to provide and use the `HeroSe
</div>
<div class="alert is-helpful">
Learn more about _providers_ in the [Providers](guide/providers) guide.
要进一步了解*提供商*,参见[服务提供商](guide/providers)一章。
</div>
## Update `HeroesComponent`
## 修改 `HeroesComponent`
@ -200,10 +193,10 @@ Open the `HeroesComponent` class file.
打开 `HeroesComponent` 类文件。
Delete the `HEROES` import as you won't need that anymore.
Delete the `HEROES` import, because you won't need that anymore.
Import the `HeroService` instead.
删除 `HEROES` 导入,你以后不会再用它了。
删除 `HEROES` 导入语句因为你以后不会再用它了。
转而导入 `HeroService`
<code-example path="toh-pt4/src/app/heroes/heroes.component.ts" title="src/app/heroes/heroes.component.ts (import HeroService)" region="hero-service-import">
@ -488,13 +481,11 @@ You should see the default paragraph from `MessagesComponent` at the bottom of t
### 创建 `MessageService`
Use the CLI to create the `MessageService` in `src/app`.
The `--module=app` option tells the CLI to [_provide_ this service](#provide) in the `AppModule`,
使用 CLI 在 `src/app` 中创建 `MessageService`
`--module=app` 选项告诉 CLI 在 `AppModule` 中[提供这个服务](#provide)。
<code-example language="sh" class="code-shell">
ng generate service message --module=app
ng generate service message
</code-example>
Open `MessageService` and replace its contents with the following.
@ -578,7 +569,7 @@ Open `MessagesComponent` and import the `MessageService`.
Modify the constructor with a parameter that declares a **public** `messageService` property.
Angular will inject the singleton `MessageService` into that property
when it creates the `HeroService`.
when it creates the `MessagesComponent`.
修改构造函数,添加一个 **public**`messageService` 属性。
Angular 将会在创建 `MessagesComponent` 的实例时 把 `MessageService` 的实例注入到这个属性中。
@ -696,9 +687,9 @@ Here are the code files discussed on this page and your app should look like thi
你把数据访问逻辑重构到了 `HeroService` 类中。
* You _provided_ the `HeroService` in the root `AppModule` so that it can be injected anywhere.
* You registered the `HeroService` as the _provider_ of its service at the root level so that it can be injected anywhere in the app.
你在根模块 `AppModule` 中提供了 `HeroService` 服务,以便在别处可以注入它。
你在根注入器中把 `HeroService` 注册为该服务的提供商,以便在别处可以注入它。
* You used [Angular Dependency Injection](guide/dependency-injection) to inject it into a component.
@ -712,7 +703,7 @@ Here are the code files discussed on this page and your app should look like thi
你发现了 `Observable` 以及 RxJS 库。
* You used RxJS `of()` to return an _Observable_ of mock heroes (`Observable<Hero[]>`).
* You used RxJS `of()` to return an observable of mock heroes (`Observable<Hero[]>`).
你使用 RxJS 的 `of()` 方法返回了一个模拟英雄数据的*可观察对象* (`Observable<Hero[]>`)。

View File

@ -550,7 +550,7 @@ fix the dashboard hero links to navigate via the _parameterized_ dashboard route
</code-example>
You're using Angular [interpolation binding](guide/template-syntax#interpolation) within the `*ngFor` repeater
to insert the current interation's `hero.id` into each
to insert the current iteration's `hero.id` into each
[`routerLink`](#routerlink).
你正在 `*ngFor` 复写器中使用 Angular 的[插值表达式](guide/template-syntax#interpolation)来把当前迭代的 `hero.id` 插入到每个 [`routerLink`](#routerlink) 中。

View File

@ -92,10 +92,10 @@ Install the *In-memory Web API* package from _npm_
npm install angular-in-memory-web-api --save
</code-example>
Import the `InMemoryWebApiModule` and the `InMemoryDataService` class,
Import the `HttpClientInMemoryWebApiModule` and the `InMemoryDataService` class,
which you will create in a moment.
导入 `InMemoryWebApiModule` 和 `InMemoryDataService` 类(你很快就要创建它)。
导入 `HttpClientInMemoryWebApiModule` 和 `InMemoryDataService` 类(你很快就要创建它)。
<code-example
path="toh-pt6/src/app/app.module.ts"
@ -103,11 +103,11 @@ which you will create in a moment.
title="src/app/app.module.ts (In-memory Web API imports)">
</code-example>
Add the `InMemoryWebApiModule` to the `@NgModule.imports` array&mdash;
Add the `HttpClientInMemoryWebApiModule` to the `@NgModule.imports` array&mdash;
_after importing the `HttpClient`_,
&mdash;while configuring it with the `InMemoryDataService`.
`InMemoryWebApiModule` 添加到 `@NgModule.imports` 数组中(放在 `HttpClient` 之后),
`HttpClientInMemoryWebApiModule` 添加到 `@NgModule.imports` 数组中(放在 `HttpClient` 之后),
然后使用 `InMemoryDataService` 来配置它。
<code-example
@ -231,8 +231,8 @@ You make a request, it returns a single response.
HTTP 是一个请求/响应式协议。你发起请求,它返回单个的响应。
In general, an `Observable` _can_ return multiple values over time.
An `Observable` from `HttpClient` always emits a single value and then completes, never to emit again.
In general, an observable _can_ return multiple values over time.
An observable from `HttpClient` always emits a single value and then completes, never to emit again.
通常,`Observable` *可以*在一段时间内返回多个值。
但来自 `HttpClient``Observable` 总是发出一个值,然后结束,再也不会发出其它值。
@ -843,8 +843,8 @@ taxing server resources and burning through the cellular network data plan.
如果每当用户击键后就直接调用 `searchHeroes()` 将导致创建海量的 HTTP 请求,浪费服务器资源并消耗大量网络流量。
Instead, the `ngOnInit()` method pipes the `searchTerms` _observable_ through a sequence of RxJS operators that reduce the number of calls to the `searchHeroes()`,
ultimately returning an _observable_ of timely hero search results (each a `Hero[]`).
Instead, the `ngOnInit()` method pipes the `searchTerms` observable through a sequence of RxJS operators that reduce the number of calls to the `searchHeroes()`,
ultimately returning an observable of timely hero search results (each a `Hero[]`).
应该怎么做呢?`ngOnInit()` 往 `searchTerms` 这个可观察对象的处理管道中加入了一系列 RxJS 操作符,用以缩减对 `searchHeroes()` 的调用次数,并最终返回一个可及时给出英雄搜索结果的可观察对象(每次都是 `Hero[]` )。
@ -863,9 +863,9 @@ before passing along the latest string. You'll never make requests more frequent
在传出最终字符串之前,`debounceTime(300)` 将会等待,直到新增字符串的事件暂停了 300 毫秒。
你实际发起请求的间隔永远不会小于 300ms。
* `distinctUntilChanged` ensures that a request is sent only if the filter text changed.
* `distinctUntilChanged()` ensures that a request is sent only if the filter text changed.
`distinctUntilChanged` 会确保只在过滤条件变化时才发送请求。
`distinctUntilChanged()` 会确保只在过滤条件变化时才发送请求。
* `switchMap()` calls the search service for each search term that makes it through `debounce` and `distinctUntilChanged`.
It cancels and discards previous search observables, returning only the latest search service observable.
@ -1033,7 +1033,7 @@ You're at the end of your journey, and you've accomplished a lot.
你配置了一个内存 Web API。
* You learned how to use Observables.
* You learned how to use observables.
你学会了如何使用“可观察对象”。