fix: sync to 6.0(WIP)
This commit is contained in:
parent
4ff1a42339
commit
2867ceecdb
|
@ -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>
|
||||
|
@ -382,6 +398,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>
|
||||
|
||||
|
@ -423,6 +456,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>
|
||||
|
||||
|
@ -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
|
||||
|
@ -548,32 +619,42 @@ These files go in the root folder next to `src/`.
|
|||
|
||||
<div class="file">e2e</div>
|
||||
|
||||
<div class='children'>
|
||||
|
||||
<div class="file">src</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>
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ 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.
|
||||
gets the correct content.
|
||||
|
||||
长周期缓存的潜在副作用之一就是可能无意中缓存了无效的资源。
|
||||
在普通的HTTP缓存中,硬刷新或缓存过期限制了缓存这种无效文件导致的负面影响。
|
||||
|
@ -508,9 +508,9 @@ an administrator ever needs to deactivate the service worker quickly.
|
|||
虽然它在设计时就尝试将此类问题的影响降至最低,但是,如果管理员需要快速停用 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
|
||||
|
|
|
@ -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`.
|
||||
|
||||
### 步骤 1:添加 Service Worker 包
|
||||
为 `theme-color` 添加 meta 标签。
|
||||
|
||||
Add the package `@angular/service-worker`, using the yarn utility as shown here:
|
||||
5. Installs icon files to support the installed Progressive Web App (PWA).
|
||||
|
||||
添加 `@angular/service-worker` 包,使用 yarn 工具时的用法如下:
|
||||
创建图标文件,以支持安装渐进式应用(PWA)。
|
||||
|
||||
```sh
|
||||
6. Creates the service worker configuration file called [`ngsw-config.json`](/guide/service-worker-config), which specifies the caching behaviors and other settings.
|
||||
|
||||
yarn add @angular/service-worker
|
||||
创建一个名叫 [`ngsw-config.json`](/guide/service-worker-config) 的 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 Worker,CLI 必须在构建时生成一个 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) 包。
|
||||
|
|
|
@ -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 的最新版本 都已经支持了。
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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` 中的方法会返回*可观察对象*。*订阅*这些方法返回的可观察对象会让它开始执行,并且断言这些方法是成功了还是失败了。
|
||||
`HttpService` 中的方法会返回 `Observables`。*订阅*这些方法返回的可观察对象会让它开始执行,并且断言这些方法是成功了还是失败了。
|
||||
|
||||
The `subscribe()` method takes a success and fail callback.
|
||||
The `subscribe()` method takes a success (`next`) and fail (`error`) callback.
|
||||
Make sure you provide _both_ callbacks so that you capture errors.
|
||||
|
||||
`subscribe()` 方法接受一个成功回调和一个失败回调。
|
||||
你要确保同时提供了这两个回调,以便捕获错误。
|
||||
|
||||
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.
|
||||
|
@ -2579,12 +2578,10 @@ Here's the `HeroDetailComponent` constructor:
|
|||
|
||||
The `HeroDetail` component needs the `id` parameter so it can fetch
|
||||
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> = {
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
## 启动应用服务器
|
||||
|
|
|
@ -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` 将用来表示所选英雄的详情。
|
||||
|
|
|
@ -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`:
|
||||
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` 已经作为该服务的提供商进行过注册。
|
||||
你要用一个*注入器*注册它。注入器就是一个对象,负责在需要时选取和注入该提供商。
|
||||
|
||||
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.
|
||||
|
||||
默认情况下,Angular CLI 命令 `ng generate service` 会通过给 `@Injectable` 装饰器添加元数据的形式,为该服务把提供商注册到*根注入器*上。
|
||||
|
||||
If you look at the `@Injectable()` statement right before the `HeroService` class definition, you can see that the `providedIn` metadata value is 'root':
|
||||
|
||||
如果你看看 `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`.
|
||||
Each option has pros and cons.
|
||||
For instance, you could have told the CLI to provide the service at the module level automatically by appending `--module=app`.
|
||||
|
||||
有很多途径可以提供 `HeroService`:在 `HeroesComponent` 中、在 `AppComponent` 中,或在 `AppModule` 中。
|
||||
每个选项都各有优缺点。
|
||||
|
||||
This tutorial chooses to provide it in the `AppModule`.
|
||||
|
||||
这节课选择在 `AppModule` 中提供它。
|
||||
|
||||
That's such a popular choice that you could have told the CLI to provide it there automatically
|
||||
by appending `--module=app`.
|
||||
|
||||
这是一个常用的选择,因此你可以通过 `--module=app` 选项让 CLI 自动把它提供给 `AppModule`。
|
||||
如果需要,你也可以在不同的层次上注册提供商 —— 在 `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[]>`)。
|
||||
|
||||
|
|
|
@ -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) 中。
|
||||
|
|
|
@ -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—
|
||||
Add the `HttpClientInMemoryWebApiModule` to the `@NgModule.imports` array—
|
||||
_after importing the `HttpClient`_,
|
||||
—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.
|
||||
|
||||
你学会了如何使用“可观察对象”。
|
||||
|
||||
|
|
Loading…
Reference in New Issue